【发布时间】:2017-03-04 06:15:09
【问题描述】:
经过数小时的搜索,我只能找到“过时”和/或“不完整”的答案。 (显然它们早于 PDO。)我正在编写 PHP 代码(版本 7.0.15),并使用 MySQL 版本 5.7.17-0(都在 KUbuntu“虚拟机”上)。虽然我从事计算机工作超过 45 年,但我对 PHP 和 MySQL 还是很陌生。
我可以在 PHP 中获取访问者的 IP 地址。然后我想检查“try_ur_table”是否已经有一个条目,如果没有,则插入一个条目并查找它,这样我就可以在程序的其他部分使用“ur_index”。 ur_index 是 int(11),ur_ip 是 binary(16)。
问题是每次运行代码,第一次select都失败了,所以新建了一条,然后第二次select也找不到匹配的!
下面是相关代码sn-p:
try
{
$pdc = new PDO('mysql:host=localhost;dbname=toy_database', 'xxxxx', 'xxxxx' );
$pdc->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdc->exec('SET NAMES "utf8"');
}
catch (PDOException $e)
{
$output = 'Unable to connect tothe databaseserver. ' . $e->getMessage();
include 'errout.html.php';
exit();
}
// Find the caller data...
if ( isset( $_SERVER[ 'REMOTE_ADDR' ] ) )
{
$cd = inet_pton( $_SERVER[ 'REMOTE_ADDR' ] );
if ( $cd )
{
// inet_pton thinks it succeeded...
try
{
$sql = "SELECT * FROM try_ur_table WHERE ur_ip = ? ";
$rt = $pdc->prepare($sql);
$rt->execute(array($cd));
$u_list = $rt->fetchAll();
}
catch (PDOException $e)
{
$output = 'Problem looking for ur_ip. ' . $e->getMessage();
include 'errout.html.php';
exit();
}
if ( $u_list == NULL )
{
// New user!
try
{
$sqm = "INSERT INTO try_ur_table SET ur_ip=?";
$rs = $pdc->prepare($sqm);
$rs->execute(array($cd));
}
catch (PDOException $e)
{
$output = 'Problem inserting new ur_ip. ' . $e->getMessage();
include 'errout.html.php';
exit();
}
// Now go find the new entry...
try
{
$sql = "SELECT * FROM try_ur_table WHERE ur_ip = ? ";
$rt = $pdc->prepare($sql);
$rt->execute(array($cd));
$u_list = $rt->fetchAll();
}
catch (PDOException $e)
{
$output = 'Problem looking for new ur_ip. ' . $e->getMessage();
include 'errout.html.php';
exit();
}
} // $u_list == NULL
// At this point there should be exactly one row in $u_list...
} // $cd != false
}
else
{
// ! isset( $_SERVER[ 'REMOTE_ADDR' ]
$cd = false;
}
其他测试表明 $_SERVER[ 'REMOTE_ADDR' ] 返回 127.0.0.1(这是有道理的,因为这是“本地主机”)。但是,每次我运行上面的代码时,phpMyAdmin 都会说 ur_ip 是 0x7f00000001000000000000000000000 (希望我已经正确计算了零 - 似乎无法从 phpMyAdmin 复制和粘贴,但这是次要的)。另外,因为我有 ur_index,所以我尝试了基于它的选择,当我尝试通过 inet_ntop() 运行 ur_ip 时,我得到了垃圾,既不是有效的 IPv4 也不是 IPv6 地址。
【问题讨论】:
-
当您插入一个新条目时,您不必返回并选择相同的数据。 PDO::lastInsertId 是你的朋友。
-
45 年?你是说当他们还是蒸汽动力的时候? ;-)
-
一般情况下,不需要“先检查”。事实上,这往往适得其反。您可以简单地提交 INSERT。如果 INSERT 失败,那么您知道 IP 已经列出。
-
@Strawberry 关于“蒸汽动力”,由于美国的大部分电力是使用蒸汽轮机(由煤、天然气或铀驱动)产生的,因此有人可以说所有我们的现代计算机中有一部分是“蒸汽驱动的”! ;-)