douzhangli9563 2015-01-14 15:55
浏览 113

无法理解语法错误,eval()'d代码中的意外'='

I've search different forms but didn't understand how to solve the problem first found here (first link, second link) but its giving me the error in eval. I can't figure it out how to solve in that code in foreach loop.

foreach($_POST as $key => $value) {
        if(!strstr($key, 'removeFile')){
                //initialize variables using eval
                eval("$" . $key . " = '" . sanitize($value) . "';");
        }
}
  • 写回答

2条回答 默认 最新

  • dongqingchan2385 2015-01-14 16:13
    关注

    First, the issues I have with your code:

    1. eval is very, very rarely needed, and extremely dangerous, use with caution. I've been developing in PHP for over 10 years, and never really encountered a situation that needed eval. This is no exception. Eval is not required
    2. You're sanitizing the entire $_POST array. That's great, but there are special functions for doing that, like: filter_input_array, array_filter and many, many more... not to mention ready-made, open source projects and frameworks that already contain a solid request validation component.
    3. Always check the return values of functions, which you seem to be doing with strstr, but be weary of functions that return different types (like strstr: it returns false if the needle isn't found, but returns 0 if the needle is found at the start of the haystack string). Your if statement might not work as intended.
    4. You're assuming sanitize($value) values will not contain any single quotes. Why? Because if they do, you'll end up with a syntax error in your evaled string

    Be that as it may, you could easily write your code using variable variables and add a simple check not to step on existing variables in scope:

    $sanitized = array_filter($_POST, 'sanitize');//call sanitize on all values
    foreach ($sanitized as $key => $value)
    {
        if (!isset($$key) && strstr($key, 'removeFile') === false)
            $$key = $value;
    }
    

    But really, $_POST values belong together, they are part of the request, and should remain grouped... either in an array, or in an object of some sort. Don't assign each value to its own variable, because pretty soon you'll loose track of what variables are set and which are not. Using an unset variable creates that variable, assigning value null, so what you have now makes for very error-prone code:

    //request 1: POST => id=123&foo=bar
    foreach ($sanitized as $k => $v)
        $$k = $v;
    $query = 'SELECT x, y, z FROM tbl WHERE id = ?';//using posted ID as value
    $stmt = $db->prepare($query);
    $stmt->execute(array($id));
    

    All is well, because $id was set, but never trust the network, don't assume that, just because $_POST is set, all the keys will be set, and their values will be correct:

    //request 2: POST => foo=bar&page=2
    foreach ($sanitized as $k => $v)
        $$k = $v;
    $query = 'SELECT x, y, z FROM tbl WHERE id = ?';//using posted ID as value
    $stmt = $db->prepare($query);
    $stmt->execute(array($id));//id is null
    

    Now we have a problem. This is just one example of how your code might cause issues. Imagine the script grows a bit, and look at this:

    //request 3: POST => id=123&foo=bar&page=2
    foreach ($sanitized as $k => $v)
        $$k = $v;
    //$id is 123, $foo is bar and $page = 2
    $query = 'SELECT x, y, z FROM tbl WHERE id = ? LIMIT 10';//using posted ID as value
    //a lot more code containing this statement:
    $page = someFunc();
    $log->write('someFunc returned log: '.$page);
    //more code
    $offset = 10*($page-1);//<-- page is not what we expected it to be
    $query .= sprintf(' OFFSET %d', $offset);
    $stmt = $db->prepare($query);
    $stmt->execute(array($id));
    

    Now this may seem far-fetched, and idiotic, but believe me: all of these things happen, more than I care to know. Adding some code that accidentally overwrites an existing variable that is used further down happens all the time. Especially in procedural code. Don't just blindly unpack an array. Keep that single variable, and use the keys to avoid:

    • grey hair
    • sudden, dramatic baldness
    • loss of sanity
    • bleeding ulcers
    • In a work environment: catastrophic loss of data
    • Sudden loss of job
    • ... because code like this makes unicorns cry, and bronies will hunt you down
    评论

报告相同问题?

悬赏问题

  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 关于大棚监测的pcb板设计
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)