
codeigniter 4 的 helper 必须是纯函数集合(无命名空间、无类),直接定义全局函数;若误用类结构或命名空间,将导致 “call to undefined function” 错误。
codeigniter 4 的 helper 必须是纯函数集合(无命名空间、无类),直接定义全局函数;若误用类结构或命名空间,将导致 “call to undefined function” 错误。
在 CodeIgniter 4 中,Helper 的设计哲学是轻量、无状态、全局可调用的函数集合——它不是类库(Library)或服务(Service),因此绝不应定义为类、不应声明命名空间、也不应使用 class 关键字封装。你当前的 Arithmetic_Helper.php 文件存在多个根本性错误,直接违反了 CI4 的 Helper 规范,导致 PHP 在运行时无法找到 get_num_words() 等函数,从而抛出 Call to undefined function App\Controllers\get_num_words() 这类典型错误(注意:错误中出现 App\Controllers\ 前缀,说明 PHP 尝试在当前控制器命名空间下查找该函数,这恰恰证明函数未被正确注册为全局函数)。
✅ 正确做法:创建纯函数式 Helper
将 app/Helpers/arithmetic_helper.php(注意文件名小写、下划线分隔,且不加 .php 后缀在加载时指定)重写为如下结构:
<?php // app/Helpers/arithmetic_helper.php
// ✅ 无命名空间|✅ 无 class 封装|✅ 所有函数为全局作用域
if (!function_exists('round_percentage')) {
/**
* Round percentage to nearest whole number
* @param float $percentage value of percentage
* @param int $precision number of decimal places
* @return string formatted percentage with '%' symbol
*/
function round_percentage(float $percentage, int $precision = 0): string
{
return round($percentage, $precision) . '%';
}
}
if (!function_exists('get_percentage')) {
/**
* Calculate percentage: (key_value / total) * 100, then round
* @param float|int $total sum of values
* @param float|int $key_value target value
* @param int $precision decimal precision for rounding
* @return string formatted percentage
*/
function get_percentage($total, $key_value, int $precision = 0): string
{
if ($total == 0 || !is_numeric($total)) {
return round_percentage(0, $precision);
}
$percentage = ($key_value / $total) * 100;
return round_percentage($percentage, $precision);
}
}
if (!function_exists('get_date_words')) {
/**
* Get human-readable time elapsed between two dates
* @param string|DateTimeInterface $datetime1
* @param string|DateTimeInterface $datetime2
* @return string e.g. '2 Days', '1 Hour', 'Just Now'
*/
function get_date_words($datetime1, $datetime2): string
{
try {
$d1 = $datetime1 instanceof DateTimeInterface ? $datetime1 : new DateTime($datetime1);
$d2 = $datetime2 instanceof DateTimeInterface ? $datetime2 : new DateTime($datetime2);
$interval = $d1->diff($d2);
} catch (Exception $e) {
return 'Invalid Date';
}
$intervals = [
'y' => ['value' => (int)$interval->format('%y'), 'unit' => 'Year', 'plural' => 'Years'],
'm' => ['value' => (int)$interval->format('%m'), 'unit' => 'Month', 'plural' => 'Months'],
'd' => ['value' => (int)$interval->format('%a'), 'unit' => 'Day', 'plural' => 'Days'],
'h' => ['value' => (int)$interval->format('%h'), 'unit' => 'Hour', 'plural' => 'Hours'],
'i' => ['value' => (int)$interval->format('%i'), 'unit' => 'Min', 'plural' => 'Mins'],
's' => ['value' => (int)$interval->format('%s'), 'unit' => 'Sec', 'plural' => 'Secs'],
];
foreach ($intervals as $code => $def) {
if ($def['value'] > 0) {
return $def['value'] . ' ' . ($def['value'] === 1 ? $def['unit'] : $def['plural']);
}
}
return 'Just Now';
}
}
if (!function_exists('get_string_time')) {
/**
* Convert datetime string to 'm/d/y' format
* @param string $datetime
* @return string formatted date
*/
function get_string_time(string $datetime): string
{
$ts = strtotime($datetime);
return $ts ? date('m/d/y', $ts) : '';
}
}
if (!function_exists('get_num_words')) {
/**
* Format large numbers into abbreviated form (e.g., 1.2k, 3.5m, 1.0b)
* @param float|int $num
* @return string
*/
function get_num_words($num): string
{
if (!is_numeric($num) || $num <p>? 加载与使用方式(关键!) </p>
文件路径:app/Helpers/arithmetic_helper.php(必须位于 app/Helpers/ 下,且文件名全小写)
-
加载方式(任选其一):
// 在 BaseController 或具体 Controller 中 protected $helpers = ['url', 'html', 'session', 'arithmetic']; // ✅ 小写、无扩展名、无驼峰 // 或手动加载 helper('arithmetic'); -
调用方式(全局函数,无需实例化):
$data['views'] = get_num_words(getViews($viewkey)); // ✅ 直接调用,无 $this-> 或 namespace
⚠️ 常见错误总结
- ❌ 使用 class Arithmetic_Helper {} → Helper 不是类,CI4 不会自动实例化或注入
- ❌ 声明 namespace App\Helpers; → 导致函数被限定在该命名空间,无法全局访问
- ❌ 文件名含大写字母(如 Arithmetic_Helper.php)或 .php 后缀 → CI4 默认按小写+无后缀匹配(helper('arithmetic') 对应 arithmetic_helper.php)
- ❌ 函数内调用未声明的同 Helper 其他函数(如 round_percentage())→ 必须用 function_exists() 包裹,或确保定义顺序(推荐统一用 if (!function_exists()) 防重定义)
- ❌ 在 .env 或配置中未启用自动加载 → 无需额外配置,只要路径正确、加载方式正确即可
? 提示:CI4 官方 Helper(如 url_helper.php)全部位于 system/Helpers/,全部采用相同模式——打开任意一个即可作为范本。坚持“函数即服务”原则,你的 Helper 就能零故障工作。










