我看了一下ajax long polling here的简介,并尝试使用wamp在我自己的电脑上模仿它,但是我遇到了一些问题。
我在longpolling.php文件第29行中一直收到有关未定义索引的错误
$num = $_GET['num'];这是因为有一个ajax get函数没有num参数导致$ _GET没有被设置。 我将代码更改为
if(isset($_GET['num'])) $num = $_GET['num']; else $num = "";
并且工作正常。但是,一旦我重新加载页面,cd计数会减少一次然后停止。
有人知道发生这种情况的原因吗? php文件(服务器)
<?php
$cd_stock = ("CdCount.txt");
function updateStock($num)
{
global $cd_stock;
$count = file($cd_stock);
$count = (int)$count[0];
$count = $count - $num;
if ($count < 0) $count = 0;
$fp = fopen($cd_stock , "w");
fputs($fp , "$count");
fclose($fp);
echo $count;
}
function getCdCount()
{
srand();
$newOrder = rand(1, 3);
$sleeptime = rand(2, 10);
sleep(2);
updateStock($newOrder);
}
if(isset($_GET['num']))
$num = $_GET['num'];
else
$num = "";
if ( $num = "")
{
getCdCount();
}
else
{
updateStock((int)$num);
}
?>
javascript文件(客户端)(使用原型框架)
Event.observe(window, 'load', function() {
Event.observe( 'btnSubmit', 'click', purchaseCD);
connectToServer();
});
function connectToServer()
{
new Ajax.Updater(
{ success: 'CD Count', failure: 'errors' },
'LongPolling.php',
{
method: 'get',
onSuccess: function(transport)
{
if (parseInt(transport.responseText)) connectToServer();
}
});
}
function purchaseCD()
{
new Ajax.Updater(
{ success: 'CD Count', failure: 'errors' },
'LongPolling.php',
{
method: 'get',
parameters: { num: $('txtQty').getValue() }
});
}
html文件真的不值得发布。它只包括ajax javascript文件和原型js文件以及相关的div等。
我一直在绞尽脑汁试图解决这个问题,但我不知道出了什么问题,并且这不是鼓励这是来自“教程”类型的文章。
答案 0 :(得分:2)
坦率地说,你的第一个问题可能存在的事实是不可原谅的。所有教程都应该假设您有最大的错误报告(如果所有这些都告诉您如何确保它发生,那将会很棒)。对你好消息? WAMP默认将错误报告设置得相当高,因此不必担心。
我也对他正在使用file
这一事实(他应该使用file_get_contents
)以及他告诉你使用文件开头这个事实也有疑问 - 它应该是$_SESSION
或更好的数据库连接。教程也应该避免使用关键字global
一定是必要的(如果教程无法管理,那么作者应该通过教程而不是编写它们)。他还认为使用一个无效CSS的ID是个好主意(你的CSS中你的ID不能有空格。这在JS中是可以接受的,但如果它不能使CSS,你为什么要这样做)。最后,他谈到了Ajax.Updater的所有好处,但他决定使用奇怪的递归方案而不是Ajax.PeriodicalUpdater。 That's what it's there for.
我的建议是抛弃该教程并开展更好的教程。就个人而言,我发现学习“旧方式”(无框架AJAX)的价值,我不得不推荐this one。如果你想使用一个框架,我个人认为你最好使用jQuery教程(比如this one),因为它更常见。如果你真的喜欢Prototype,还有其他更简单的例子 - this one似乎非常紧张。
如果您觉得这是真正的教程,那么最重要的是,您可以采取一些措施来帮助自己解决这个问题。你没有任何明显的编码错误,所以我能做的最多就是给你建议:
if (parseInt(transport.responseText)) setTimeout(connectToServer, Math.rand() * 4000 + 1000);
(将延迟放在客户端而不是服务器端)。 sleep
实际上只应在非常罕见的情况下使用。console.log
(如果您没有使用像Firebug这样的网络开发者工具(如果不是......为什么不这样做?),请致电transport.responseText
。如果服务器返回0,则不会再次触发connectToServer方法。因此,了解该值的用途可能很有用。