【发布时间】:2015-09-14 22:11:21
【问题描述】:
对 PHP 很陌生,我被困在一个(我认为)一个奇怪的问题上。我已经将这个文件拼接在一起,(它被分割成几个不同的函数)进行测试,并且更容易解释这个问题。
这是 Laravel 中的一个基本 while 循环,它似乎过早退出,但奇怪的是没有退出到循环之后的行,而是在循环之前退出然后再次进入。不能为我的生活锻炼为什么。我在整个函数中添加了一些日志事件,以便我可以尝试了解发生了什么。
在第 7 页之前,这可以正确地获取产品并将其写入数据库,然后我在日志中收到“启动 API 帮助程序”事件,但从未收到“结束 API 帮助程序”。因此,在第 7 页的某处某处导致 while 循环退出到上面的行,将 pagecount 重置为 0。然后重新进入循环,获取第一批产品并在写入时抛出 SQL 重复键异常。我知道它正在退出到循环之前,因为我在日志中的“新客户端”之后得到“之前”。当然,页数正在重置。这怎么可能发生?
任何帮助将不胜感激。
public function store()
{
$items = array();
Log::info('Before while');
$pagecount = 0;
$prodcount = 1;
while ($prodcount > 0) {
Log::info('Top of while');
$prodcount = 0; // Reset product counter
Log::info('Page Count:'.$pagecount);
Log::info('Start API Helper');
$headers = array(
'NETOAPI_KEY' => env('NETO_API_KEY'),
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'NETOAPI_ACTION' => 'GetItem'
);
Log::info('Headers Declared');
$body = '{
"Filter": {
"DateAddedFrom" : "2013-06-01 12:00:00",
"Page": "'.$pagecount.'",
"Limit": "500",
"OutputSelector": [
**Lots of JSON here - removed for readability**
]
}
}';
Log::info('Start API Helper');
$client = new client();
Log::info('New Client');
try {
$res = $client->post(env('NETO_API_URL'), [ 'headers' => $headers , 'body' => $body ]);
} catch (RequestException $e) {
echo $e->getRequest();
Log::error($e->getRequest());
if ($e->hasResponse()) {
echo $e->getResponse();
Log::error($e->getResponse());
}
}
Log::info('End API Helper');
$items = json_decode(utf8_encode($res->getBody()), true);
foreach($items["Item"] as $item)
{
// JSON is returning an empty array for empty strings. Need to convert to empty string for SQL save.
foreach($item as $key => $value){
if (empty($value)) {
$item["$key"] = "";
}
}
$Product = new Item;
$Product->SKU = array_get($item, 'SKU');
** LOTS OF DB FIELDS REMOVED FROM HERE FOR READABILITY**
$Product->save();
$prodcount++;
}
$pagecount++;
Log::info($prodcount.' products written to DB:');
Log::info('Bottom of while');
};
Log::info('Exited While');
return 'Complete';
}
更新:我已将 ELoquent SQL 客户端修改为 firstorNew 以避免任何潜在的重复键错误。现在日志在第 7 页(偶尔在第 8 页)显示相同的“while exit”,然后在第 0 页重新进入循环,但最奇怪的是它似乎最终以 2 个循环实例运行。然后最终是 3 个实例,然后是 4 个。然后它抛出一个内存耗尽异常。日志看起来像。
local.INFO: Page Count:1
local.INFO: Page Count:2
local.INFO: Page Count:3
local.INFO: Page Count:4
local.INFO: Page Count:5
local.INFO: Page Count:6
local.INFO: Page Count:7
local.INFO: Page Count:8
local.INFO: Page Count:0
local.INFO: Page Count:9
local.INFO: Page Count:1
local.INFO: Page Count:10
local.INFO: Page Count:2
local.INFO: Page Count:11
local.INFO: Page Count:3
local.INFO: Page Count:12
...等等...
格式错误的 JSON API 响应是否可能导致此问题?也许我会尝试将分页限制在 25 左右,这样我就可以访问导致循环中断的响应?
【问题讨论】: