调用getData()报null错误:已初始化$api为何仍未定义?
问题
我是开发领域新手,请多包涵。我编写了一个包含若干方法的类,使用Workerman启动服务器,希望在服务器启动时通过function load()加载CSV数据,之后在API请求时根据传入的$key返回对应数据。
CSV数据如下:
doctor,31234-32223 police officer,342-341 firefighter,543-3345 worker,12223 developer,120045
我编写的App类代码如下:
class App { public $getPair = null; public $dataToLoad= []; protected $dispatcher = null; /** * start */ public function start() { $this->dispatcher = \FastRoute\simpleDispatcher(function(\FastRoute\RouteCollector $r) { foreach ($this->routeInfo as $method => $callbacks) { foreach ($callbacks as $info) { $r->addRoute($method, $info[0], $info[1]); } } }); \Workerman\Worker::runAll(); } function load() { $files = "load.csv"; foreach($files as $file) { if (($handle = fopen($file, "r")) !== FALSE) { while (($data = fgetcsv($handle, 4096, ",")) !== FALSE) { $dataToLoad[$data[1]] = $data[0]; } fclose($handle); } } return $this->dataToLoad; } function getData($getPair) { foreach ($this->dataToLoad as $key => $value){ if($getPair === $key){ return array($key.','.$value); } else { echo "missing"; } } } /** * @param TcpConnection $connection * @param Request $request * @return null */ public function onMessage($connection, $request) { static $callbacks = []; try { $path = $request->path(); $method = $request->method(); $key = $method . $path; $callback = $callbacks[$key] ?? null; if ($callback) { $connection->send($callback($request)); return null; } $ret = $this->dispatcher->dispatch($method, $path); if ($ret[0] === Dispatcher::FOUND) { $callback = $ret[1]; if (!empty($ret[2])) { $args = array_values($ret[2]); $callback = function ($request) use ($args, $callback) { return $callback($request, ... $args); }; } $callbacks[$key] = $callback; $connection->send($callback($request)); return true; } else { $connection->send(new Response(404, [], '<h1>404 Not Found</h1>')); } } catch (\Throwable $e) { $connection->send(new Response(500, [], (string)$e)); } } }
index.php代码如下:
use Mark\App; $api = new App('http://0.0.0.0:3000'); $api->count = 4; // process count $api->load(); //load data $api->get('/key/{key}', function ($request, $key) { return $api->getData("doctor"); }); $api->start();
错误信息:
Error: Call to a member function getData() on null
PHP Warning: Undefined variable $api
明明我已通过new App()初始化了$api,为何会出现getData()调用时为null、$api未定义的问题?注:服务器可正常启动且无报错。
解决方案
1. 核心问题:闭包变量作用域
路由回调函数默认不会继承外部作用域的$api变量,所以当请求触发回调时,PHP找不到$api变量,导致报错。
修复方法:在闭包中通过use关键字显式引入$api,同时把固定的"doctor"改成请求传入的$key参数:
$api->get('/key/{key}', function ($request, $key) use ($api) { return $api->getData($key); });
2. 修复App类中的逻辑错误
除了作用域问题,你的App类还有几处错误需要修正:
(1) load方法的错误
$files = "load.csv";是字符串,不能用foreach遍历,直接使用文件名即可- 给类属性赋值时必须加
$this->,否则会创建局部变量,无法更新类的$dataToLoad属性
修正后的load方法:
function load() { $file = "load.csv"; if (($handle = fopen($file, "r")) !== FALSE) { while (($data = fgetcsv($handle, 4096, ",")) !== FALSE) { $this->dataToLoad[$data[1]] = $data[0]; } fclose($handle); } return $this->dataToLoad; }
(2) getData方法的逻辑问题
- 原循环会在第一个不匹配的key就输出"missing",导致多次无效输出,且无法正确处理找不到key的情况
- 可以直接利用数组索引查找,不需要循环遍历
修正后的getData方法:
function getData($getPair) { if (isset($this->dataToLoad[$getPair])) { return [$getPair . ',' . $this->dataToLoad[$getPair]]; } return ["missing: {$getPair}"]; }
3. 最终修正后的index.php
use Mark\App; $api = new App('http://0.0.0.0:3000'); $api->count = 4; // process count $api->load(); //load data $api->get('/key/{key}', function ($request, $key) use ($api) { return $api->getData($key); }); $api->start();
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

