一次PHP中SQL的Where子句无效问题的解决之旅

大概有五、六、七、八、九年没有使用PHP了, 这两天突然被一个跨站点的同仁问了一个PHP的问题,据描述这个问题已经折磨他三天了。

问题厘清

他的问题是: “PHP里面调用MySQL 查询的问题, 在Windows执行正常,但是放到Linux下就有问题了”。
收到这个问题描述, 我的第一反应是有可能是PHP或者是MySQL模块的版本原因,于是我回复如下:
” 我这边猜想有可能是PHP 的 MySQL版本的原因,
因为PHP的MySQL模块升级后, SQL语法上有一些差异“。

所以我让他查看一下PHP的相关版本,可以他对PHP不熟悉,在Linux下也不知道如何查看PHP相关版本。
于是我让他共享桌面,才完整的看清了整个问题的全貌。
他的环境和功能是:

  1. 在浏览器中输入某些条件后查询MySQL数据库的某张表
  2. 有两个php文件,一个输入查询条件,一个显示查询结果
  3. 服务器使用的是Apache
    真正的问题是:
    在第一个页面不管输入什么条件,都会把该表中所有的数据查询出来。看上去后面的Where子句没有任何结果。

问题探索

应用的环境

从以上的观察来看, 我更进一步相信有可能是版本的原因, 于是我让他查看PHP相关的配置。首先需要解决的问题是在Linux中找到Apache和PHP的安装目录,查找方式是通过whereis命令, 比如查找php相关的目录:
whereis php

接下来是查看PHP的相关配置,我首先提供给的方式是:

  1. 在apache 的htdocs目录(或子目录)下创建一个phpinfo.php的文件,该文件的内容很简单:
<?php
    phpinfo();
?>
  1. 添加完成后在浏览器输入 http://xxxx/php.info.php 之后就会显示PHP的版本、环境变量以及安装模块等配置信息。

查看PHP的配置信息 ,在Windows下也可以直接查看php.ini的文件内容, 如果只是需要获取PHP版本,也可以在命令行输入:
php -version进行查看。

从查看的版本结果看, 在Windows和Linux下的版本的确不一致, 一个是PHP 5另外一个是PHP 7。是否真是版本原因导致的呢?

代码分析

从以上的分析看, 原因出现在SQL的执行上,很有可能是MySQL模块的版本原因, 于是就需要查看源码, 源码倒也简单,这里简化一下两个页面的代码:

  1. input.php, 输入查询条件页面
<html>
  <head>
    <title>Query</title>
  </head>
  <body>
    <form action="result.php" method="Post">
       Name:
       <input type="Text" name="name"> 

      <input type="Submit"><br>
    </form>
  </body>
</html>

  1. result.php 执行查询并显示查询结果页面
<html>
    <head>
        <title>Result</title>
    </head>
<body>

<?
$NAME=$_REQUEST["name"];
?>
	
<?php
    $conn =mysqli_connect("localhost","root","123456","oscar999"); 
    $sql_query = "SELECT userid,name,sex FROM user where name like '$NAME%'";
    $result = $conn->query($sql_query);  
    
    if ($result->num_rows > 0) {
        while($row = $result->fetch_assoc()) {
            echo "id: " . $row["userid"]. " - Name: " . $row["name"]. " " . $row["sex"]. "<br>";
        }
	} else {
		    echo "No result";
	}		    
	$conn->close();
?>

</body>
</html>

对以上代码说明如下:

  • $_REQUEST["name"]; 通过$_REQUEST获取请求参数
  • SQL 语句很简单,where 子句中属性Like 一个参数。
解决思路

根据以上代码,首先的解决思路是:是不是因为版本等原因,SQL不能正确执行呢?

验证方式是把SQL 中where 的变量参数换成常量, 发现是正常的,所以MySQL查询是没有问题的。

既然SQL语句没有问题,那是不是因为前端的参数没有正确传递呢?
通过echo 打印传递的参数,

echo $NAME; 

在浏览器报变量未定义的错误。

Notice: Undefined variable: NAME in

于是,问题定位了, 因为参数没有正确的传递, Where子句没有生效,所以每次都会将所有的数据找出来。

在回头细看代码,Oh My God,在获取参数的地方少了一个 php语言的标签。也就是在以下代码:

<?
$NAME=$_REQUEST["name"];
?>

<? 后面少了一个 php,正确的形式应该是:

<?php
$NAME=$_REQUEST["name"];
?>

总结

这个问题应该属于一个低级问题,导致的原因很大部分是因为粗心。但是出现问题的时候,处理起来却又是非常耗时的。特别是如何结合了一些假象,处理起来就更容易被误导。比如:

  1. 那个环境可以,这个环境不可以
  2. 以前是正常的,现在有问题

另外,这个问题出现不易发现的原因是没有任何错误出现,类似这里不是显示不出数据,而是把数据全部显示出来。
在实际开发中,除了养成细心的编程习惯外,也可以借助一些IDE开发工具提早发现这些错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

oscar999

送以玫瑰,手留余香

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值