重新打开:PHP array_shift(); VS 重置();未设置();数组拼接();
Posted
技术标签:
【中文标题】重新打开:PHP array_shift(); VS 重置();未设置();数组拼接();【英文标题】:Reopened: PHP array_shift(); VS reset(); unset(); array_splice(); 【发布时间】:2012-09-12 08:02:20 【问题描述】:重新打开:
由于 php 是一种服务器端语言,我假设我使用什么浏览器并不重要,但显然并非如此。我一直在使用谷歌浏览器。
我在本地计算机上安装了 WAMP,因此我可以在本地对其进行测试,看看它是否与我的共享主机帐户一样。两种代码都按应有的方式工作(在 Chrome 中提醒您)。然后我查看了共享主机上完全相同的代码——一个有效,另一个无效。
我打电话给我的共享主机支持,他们试图复制问题并说他们没有找到它。因此,我在 Firefox 和 IE 中尝试了它,并且在 IE 中尝试了它,你瞧……它在两者中都能完美运行,就像在 WAMP 上一样。
这对我来说仍然没有多大意义。我在与一家知名托管公司的共享托管帐户上使用 PHP 5.3,但由于他们无法真正解决代码问题,因此无处可去。他们可以复制问题,但无法回答原因。我将在接下来的几周内尝试了解更多信息,并在我了解更多信息后发布更新。
我想做的是:
生成一系列数字 将它们随机排列 将随机排序的数字数组复制到会话数组中 获取数组的第一个值,删除该值,然后全部移位 值减一这是我的问题:
我尝试使用array_shift();
,它在第一次运行时运行良好,但每次我运行代码后它都会删除前两个元素。
为了测试发生了什么,我尝试先打印数组,执行array_shift();
,然后再次打印数组以查看发生了什么。
预期结果:
运行#1:
[0]=>5 [1]=>2 [2]=>1 [3]=>4 [4]=>3 //print_r($array);
//execute array_shift($array);
[0]=>2 [1]=>1 [2]=>4 [3]=>3 //print_r($array);
运行#2:
[0]=>2 [1]=>1 [2]=>4 [3]=>3 //print_r($array);
//execute array_shift($array);
[0]=>1 [1]=>4 [2]=>3 //print_r($array);
实际结果:
运行#1:
[0]=>5 [1]=>2 [2]=>1 [3]=>4 [4]=>3 //print_r($array);
//execute array_shift($array);
[0]=>2 [1]=>1 [2]=>4 [3]=>3 //print_r($array);
运行#2:
[0]=>1 [1]=>4 [2]=>3 //print_r($array);
//execute array_shift($array);
[0]=>4 [1]=>3 //print_r($array);
我的问题(续)
然后我尝试使用reset($array);
、unset($array[0]);
和array_splice($array,1,0);
作为array_shift($array) 的替代方案;它奏效了!然后我试着并排比较它们
并清理了代码,现在他们正在做相反的事情。有时reset、unset和array_shift;一次调用时甚至会跳过数组中的最多 7 个单元格。 array_shift();
正在按照我现在想要的方式工作,但我想知道为什么。快把我逼疯了!如果有人可以帮助我,我将不胜感激。
代码转储:
取消、重置、拼接
<?php
session_start();
$min = A;
$max = S;
if((!isset($_SESSION['image'])) || ($_SESSION['image'] == null))
$numbers = range($min, $max); //set a range for all images
shuffle($numbers); //shuffle the order for randomness
$_SESSION['image'] = $numbers;
echo "<br />Current value: " . $_SESSION['image'][0] . "<br />";
print_r($_SESSION['image']);
reset($_SESSION['image']);
unset($_SESSION['image'][0]);
array_splice($_SESSION['image'],1,0);
echo "<br />New value: " . $_SESSION['image'][0] . "<br />";
echo "<br />1st exec<br />";
else
echo "<br />Current value: " . $_SESSION['image'][0] . "<br />";
print_r($_SESSION['image']);
reset($_SESSION['image']);
unset($_SESSION['image'][0]);
array_splice($_SESSION['image'],1,0);
echo "<br />New value: " . $_SESSION['image'][0] . "<br />";
echo "<br />2nd exec<br />";
?>
班次
<?php
session_start();
$min = A;
$max = S;
if((!isset($_SESSION['id2'])) || ($_SESSION['id2'] == null))
$numbers = range($min, $max); //set a range for all images
shuffle($numbers); //shuffle the order for randomness
$_SESSION['id2'] = $numbers;
echo "<br />Current value: " . $_SESSION['id2'][0] . "<br />";
print_r($_SESSION['id2']);
array_shift($_SESSION['id2']);
echo "<br />New value: " . $_SESSION['id2'][0] . "<br />";
echo "<br />1st execution<br />";
else
echo "<br />Current value: " . $_SESSION['id2'][0] . "<br />";
print_r($_SESSION['id2']);
array_shift($_SESSION['id2']);
echo "<br />New value: " . $_SESSION['id2'][0] . "<br />";
echo "<br />2nd execution<br />";
?>
【问题讨论】:
在您的第一次和第二次运行之间是否有任何机会(可能是一些 javascript)正在创建另一个请求? 这就是我想知道的。这些页面上没有其他内容。这些是完整的转储。您可以在以下位置查看它们的示例:[link]jeffbooru.com/test.php [link]jeffbooru.com/test2.php 在你的 $_SESSION 中设置一个计数器,这样你就知道代码被调用的频率(这是一种廉价的调试方法)。 我会完全关闭我的浏览器然后重新运行它,但我知道你的意思。我会在今晚晚些时候在家时实施它。想一想,在上面插入计数器的好方法是什么?它不会根据是否设置而变为真或假吗? test.php 执行了 2 个 array_shift 调用,而 test2.php 只执行了一个,您确定您正在运行您在此处编写的实际代码吗?您可以通过刷新每一页来查看我的结果。运行 test.php 时还会出现第二个 exec 文本,这意味着您可能错过了 else 那里。我怀疑您在编辑时忘记更新这两个文件,并且只有 test2 具有最新版本。 【参考方案1】:为了最终了解发生了什么,我建议register a tick-function。滴答函数可以在每个 PHP 语句执行时执行。
这是一个简单的,跟踪每个语句的行/文件(请随时添加更多详细信息):
// Execute at each single statement
declare(ticks=1);
// Function to get called at each executing statement
function logEachStatement()
$traceInfo = debug_backtrace();
$lastActivation = $traceInfo[ count( $traceInfo ) - 1 ];
$info = "\n"
. $lastActivation[ 'line' ] . '@' . $lastActivation[ 'file' ]
;
$targetFile = dirname( __FILE__ ) . '/stmnt.log' );
file_put_contents( $targetFile, $info, FILE_APPEND );
// using a function as the callback
register_tick_function( 'logEachStatement', true );
虽然还有其他方法可以追踪问题,但此方法不需要外部基础架构。
【讨论】:
【参考方案2】:假设您粘贴了实际代码,发生这种情况的唯一方法是您发出了无意的中间请求。但是,仅凭给定的信息,我们不可能确定这种情况的发生方式或原因。
我的建议是使用您选择的浏览器开发工具(例如 Firebug)并监控网络选项卡以确保只有一个请求被发送到脚本。如果这没有出现您的问题,请添加一些简单的调试日志记录,例如:
$log = date('Y-m-d H:i:s')
. ' :: Request received from '
. $_SERVER['REMOTE_ADDR']
. "\n";
file_put_contents('/path/to/your/log/file', $log, FILE_APPEND);
然后在测试后检查您的日志以确保只添加了一个条目。
【讨论】:
这是真正的代码。我正准备把自己扔出窗外试图弄清楚这一点。 array_shift 被分解,直到我尝试使用reset、unset 和array_splice 重写它。我很高兴看到我没有疯。以上是关于重新打开:PHP array_shift(); VS 重置();未设置();数组拼接();的主要内容,如果未能解决你的问题,请参考以下文章
[PHP源码阅读]array_pop和array_shift函数