【问题标题】:Strange PHP and Codeigniter奇怪的 PHP 和 Codeigniter
【发布时间】:2015-10-19 11:31:25
【问题描述】:

我有一个从 MySQL 数据库中获取用户详细信息的函数。 如果提供的函数参数是整数,则函数将其视为用户 ID,如果参数是字符串,则检查字符串是否是预定义数组中的键,如果参数是数组中的键,则将参数视为user_group id(从配置文件中获取),如果参数是字符串但不在数组键中,则将参数视为用户名,如果不满足任何条件则抛出错误。

问题:如果我为函数提供用户名(字符串),它应该可以正常工作。如果我提供一个字符串,它是预定义数组中的一个键,那么它就可以工作。 如果我提供用户 ID (int),它适用于除 1 之外的所有 ID。也就是说,如果$param 为 1,它会给我“错误 3”(代码下方),如果提供的整数是数据库中的任何其他 id,那么它可以工作。 id 1 确实存在于数据库中。奇怪的是,即使提供的 id 为 1,var_dump() 实际上也会转储正确的数据。

这是最后一个查询字符串:SELECT * FROM user as u JOIN user_details as ud ON u.id = ud.id_user WHERE u 987654331@ = '1'

显然它将 1 视为字符串而不是整数。 为什么?为什么它仍然在获取第一条记录(id=1),尽管它将 id 视为用户名u.username = '1'?

如果我在function _initialize ( $param ) 的开头添加$param = 1;,则会收到以下错误。

致命错误:允许的内存大小为 134217728 字节已用尽(已尝试 分配 49 个字节)在 E:\APACHE\htdocs\codeigniter\lib\system\database\DB_query_builder.php 第 2677 行

protected function _initialize ( $param )
{

    $this->ci->db->select (  '*'  );
    $this->ci->db->from ( $this->tableUser [ 'table' ] . ' as u' );
    $compare = NULL;

    if (  is_int ( $param )  ){
        $compare = $this->tableUser [ 'column' ] [ 'id' ];
    }
    elseif ( is_string ( $param ) && array_key_exists (  $param, $this->constantsServices  )  ){
        $compare = $this->tableUser [ 'column' ] [ 'id_user_groups' ];
        $param = $this->constantsServices [ $param ];
    }
    else if (  is_string ( $param )  ){
        $compare = $this->tableUser [ 'column' ] [ 'username' ];
    }else {
        throw new Exception ( 'Error 1' );
    }


    $this->ci->db->where ( 'u.' . $compare, $param );
    $this->ci->db->join (  $this->tableUserDetails [ 'table' ] . ' as ud', 'u.' . $this->tableUser [ 'column' ] [ 'id' ] . ' = ud.' . $this->tableUserDetails [ 'column' ] [ 'id_user' ]  );
    $query = $this->ci->db->get (  );

    if ( ! $query ){
        throw new Exception ( 'Error 2' );
    }

    $data = $query->unbuffered_row('array');

    var_dump ( $data );

    if ( !isset ( $data ) ){
        throw new Exception ( 'Error 3' );
    }
}

【问题讨论】:

  • 我建议尝试给这个问题一个更好的标题,以吸引能够帮助你的人。
  • @TomHart 这是个好主意,谢谢,但我的标题很糟糕:(
  • preg_match 本质上并不是测试数值的更好或更坏的方法。这只是一种不同的方式。如果您正在循环,则 is_numeric 或(对于整数可能更好) ctype_digit 就资源而言可能更好。只是出于好奇,如果您注释掉第一个 elseif 块会发生什么?

标签: php mysql codeigniter codeigniter-3


【解决方案1】:

您应该使用正则表达式来找出数字/数字值。 而不是 is_int 使用

if(preg_match('/^\d+$/',$param))
{
    //Your code goes here
    // Then typecast your parameter as 
    $param = (int)$param
}

【讨论】:

  • 这给了我错误:> Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 580 bytes) in E:\APACHE\htdocs\codeigniter\lib\system\database\drivers\mysqli\mysqli_driver.php on line 221
  • 你可以尝试在phpmyadmin中回显查询和计数记录吗?
  • 是的,我做到了,问题中提到了。似乎内存分配问题是由我猜的某个循环引起的。
  • 加一个是为了更好地测试数值。
【解决方案2】:

is_int checks if the variable is a php int 因此,如果传递了一个字符串,则会得到 false。尝试使用 is_numeric 并可能将其转换为 int。

这不会解决您在内存方面遇到的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    • 2016-06-17
    • 1970-01-01
    • 2013-09-04
    • 2011-01-01
    相关资源
    最近更新 更多