OpenCart Payment plugin 报 render() 未定义错误
结论
这是典型的 OpenCart 版本 API 混用问题。
当前控制器采用的是 OpenCart 1.5 的渲染方式:
$this->data
$this->template
$this->children
$this->render()
实际运行环境很可能是 OpenCart 2.x 或 3.x。这些版本通常不再通过 $this->render() 输出页面,而是把数据放入 $data,再调用:
$this->response->setOutput(
$this->load->view('payment/cipg_sim.tpl', $data)
);
所以,只把 $this->data 替换为 $data 并不能解决问题。代码末尾仍会调用不存在的 $this->render(),页面也就无法正常输出。如果服务器关闭了 PHP 错误显示,浏览器中可能只会出现空白页。
OpenCart 2.x 的修改方法
先把控制器中的所有:
$this->data['key']
改为:
$data['key']
然后删除旧版的渲染配置:
$this->template = 'payment/cipg_sim.tpl';
$this->children = array(
'common/header',
'common/footer'
);
$this->response->setOutput($this->render());
改用 OpenCart 2.x 的写法:
$data['header'] = $this->load->controller('common/header');
$data['column_left'] = $this->load->controller('common/column_left');
$data['footer'] = $this->load->controller('common/footer');
$this->response->setOutput(
$this->load->view('payment/cipg_sim.tpl', $data)
);
控制器的主要结构可以写成:
<?php
class ControllerPaymentCipgSim extends Controller
{
private $error = array();
public function index()
{
$this->load->language('payment/cipg_sim');
$this->document->setTitle(
$this->language->get('heading_title')
);
$this->load->model('setting/setting');
if (
$this->request->server['REQUEST_METHOD'] == 'POST'
&& $this->validate()
) {
$this->model_setting_setting->editSetting(
'cipg_sim',
$this->request->post
);
$this->session->data['success'] =
$this->language->get('text_success');
$this->response->redirect(
$this->url->link(
'extension/payment',
'token=' . $this->session->data['token'],
true
)
);
}
$data['heading_title'] =
$this->language->get('heading_title');
$data['text_enabled'] =
$this->language->get('text_enabled');
$data['text_disabled'] =
$this->language->get('text_disabled');
if (isset($this->request->post['cipg_sim_status'])) {
$data['cipg_sim_status'] =
$this->request->post['cipg_sim_status'];
} else {
$data['cipg_sim_status'] =
$this->config->get('cipg_sim_status');
}
$data['action'] = $this->url->link(
'payment/cipg_sim',
'token=' . $this->session->data['token'],
true
);
$data['cancel'] = $this->url->link(
'extension/payment',
'token=' . $this->session->data['token'],
true
);
$data['header'] =
$this->load->controller('common/header');
$data['column_left'] =
$this->load->controller('common/column_left');
$data['footer'] =
$this->load->controller('common/footer');
$this->response->setOutput(
$this->load->view('payment/cipg_sim.tpl', $data)
);
}
protected function validate()
{
if (
!$this->user->hasPermission(
'modify',
'payment/cipg_sim'
)
) {
$this->error['warning'] =
$this->language->get('error_permission');
}
return !$this->error;
}
}
模板需要直接使用控制器传入的变量,例如:
<?php echo $header; ?>
<?php echo $column_left; ?>
<div id="content">
<h1><?php echo $heading_title; ?></h1>
</div>
<?php echo $footer; ?>
如果模板仍然依赖旧版 $this->data 或旧版子控制器输出方式,即使控制器已经修改,页面仍可能空白或缺少布局。
如果使用的是 OpenCart 3.x
OpenCart 3.x 默认使用 Twig,因此控制器写法和模板路径还要进一步调整。常见写法如下:
$data['header'] = $this->load->controller('common/header');
$data['column_left'] = $this->load->controller('common/column_left');
$data['footer'] = $this->load->controller('common/footer');
$this->response->setOutput(
$this->load->view('extension/payment/cipg_sim', $data)
);
模板通常位于:
admin/view/template/extension/payment/cipg_sim.twig
后台令牌一般也要从:
token
改为:
user_token
例如:
$data['action'] = $this->url->link(
'extension/payment/cipg_sim',
'user_token=' . $this->session->data['user_token'],
true
);
OpenCart 2.0、2.2、2.3 和 3.x 的扩展目录、路由及模板规则不完全相同,不能只修改一个渲染调用。应参照当前安装版本自带的支付模块,使用相同的目录结构和控制器写法进行迁移。
为什么替换成 $data 后是空白页
$this->data 和 $data 不能单独互换,因为它们属于不同的页面渲染流程。
旧版流程大致如下:
$this->data['heading_title'] = '...';
$this->template = 'payment/cipg_sim.tpl';
$this->response->setOutput($this->render());
新版流程则是:
$data['heading_title'] = '...';
$this->response->setOutput(
$this->load->view('payment/cipg_sim.tpl', $data)
);
如果只替换变量,却保留:
$this->render()
控制器仍然会调用不存在的方法。反过来,如果实际运行的是 OpenCart 1.5,却把数据改为局部变量 $data,旧版 render() 不会自动读取该变量,模板同样拿不到数据。
空白页通常不表示错误已经消失,而是 PHP 关闭了 display_errors。可以查看:
system/storage/logs/error.log
部分旧版本的日志可能位于:
system/logs/error.txt
也可以到 OpenCart 后台的错误日志页面查看具体异常。
还需要检查控制器名称
错误信息中的类名是:
ControllerPaymentStanbic
代码使用的模块名和路由却是:
cipg_sim
payment/cipg_sim
这表明实际加载的控制器、文件名、类名和路由可能没有统一。以旧式支付模块目录为例,各项名称通常需要保持对应:
文件:admin/controller/payment/cipg_sim.php
类名:ControllerPaymentCipgSim
路由:payment/cipg_sim
语言:payment/cipg_sim
模板:payment/cipg_sim.tpl
如果文件实际是:
admin/controller/payment/stanbic.php
类名就应与文件名对应:
class ControllerPaymentStanbic extends Controller
相关路由、语言文件和模板路径也应统一使用 stanbic,或者全部改为 cipg_sim。两个模块标识不能混用。
其他代码问题
代码开头显示为:
load->language('payment/cipg_sim');
如果源文件中确实是这样,而不是复制时漏掉了内容,应改为:
$this->load->language('payment/cipg_sim');
另外,validate() 中的权限检查被注释掉了。支付模块保存配置时应恢复权限验证:
if (!$this->user->hasPermission('modify', 'payment/cipg_sim')) {
$this->error['warning'] =
$this->language->get('error_permission');
}
也不建议直接拼接 HTTPS_SERVER:
HTTPS_SERVER . 'index.php?route=...'
应使用当前版本支持的 $this->url->link() 和 $this->response->redirect(),以便正确处理后台地址、HTTPS、令牌和 URL 编码。
解决这个问题不能只替换 $this->data。控制器、模板、路由和令牌处理都需要按当前 OpenCart 版本的扩展结构完整迁移。
备注:内容仅供参考。
