挖路哥面试出的一道笔试题

一般如果都能回答上来的话应该就是可以毕业的phper了,之后再在面试中交流经验等方面。

问题

请找出下面代码中的问题,修复并优化。

<?php
//批量注册用户,每次>100个。
//注册新用户,要求用户名与email不能与以前的重复。
$mysqli = new Mysqli($host, $user, $pass);
for ($i=0; $i<count($_POST['user_info']); $i++) {
    $info = $_POST['user_info'][$i];
    $re_1 = $mysqli->query("SELECT * FROM `demo` WHERE `uname`=$info['uname']");
    $re_2 = $mysqli->query("SELECT * FROM `demo` WHERE `email`=$info['email']");
    if (!$re_1 || !$re_2) {
        $mysqli->query("INSERT INTO `demo` (`uname`, `email`) VALUES('$info['email']', '$info['uname']')");
    }
}

见解

  • count函数放到循环外面用变量替代,这样count函数不会随着循环的不断调用而产生相同的结果。
  • 字符串拼接数组的时候要用{}包起来,避免不能解析。
  • 逻辑关系不对,$re_1和$re_2应该是都不为真的时候在执行插入,即:!$re_1 && !$re_2。
  • insert语句的字段和值对应顺序不对,要仔细看一下得。
  • 循环里面不要套sql语句,在循环里面拼接好sql语句,最后统一执行这一条sql语句。
  • for最好用foreach替换,操作方便,效率高一点。
  • 入库之前之前要参数过滤,用框架多了,这些框架都做了。自己写原生的话要过滤一下,用mysqli->real_escape_string最佳。
  • 入库之前最好做一点初始化工作,例如:选择数据库,设置编码等。

最后自己改写一下,也算是复习一下mysqli了

<?php
//批量注册用户,每次>100个。
//注册新用户,要求用户名与email不能与以前的重复。
$infos = isset($_POST['user_info']) ? $_POST['user_info'] : array();
if (!empty($infos)) {
    $mysqli = new Mysqli($host, $user, $pass);
    $names_res = $mysqli->query('SELECT `uname` FROM `demo`');
    $names = $names_res->fetch_assoc();
    $emails_res = $mysqli->query('SELECT `email` FROM `demo`');
    $emails = $emails_res->fetch_assoc();
    $sql    = "INSERT INTO `demo` (`uname`, `email`) VALUES ";
    foreach ($infos as $info) {
        $info['uname'] = $mysqli->real_escape_string($info['uname']);
        $info['email'] = $mysqli->real_escape_string($info['email']);
        if (!in_array($info['name'], $names) && !in_array($info['email'], $emails)) {
            $sql .= '(' . $info['uname'] . ', ' . $info['email'] . '),';
        }
    }
    $mysqli->query($sql) or die($mysqli->error());
}

如果大家有更好的经验,还望分享一二。

友荐云推荐