2013-07-24 4 views
1

Итак, я работаю над преобразованием старого учебника, который я сделал некоторое время назад от mySQL до PDO. Таким образом, я могу лучше понять концепции. Кажется, я, похоже, столкнулся с стеной. Следующая функция дает мне ошибкупреобразование в PDO, проблемы

function user_data($user_id, $db) { 
    $data = array(); 
    $user_id = (int)$user_id; 

    $func_num_args = func_num_args(); 
    $func_get_args = func_get_args(); 

    if($func_num_args > 1) { 
     unset($func_get_args[0]); 
     $fields = '`' . implode('`, `', $func_get_args) . '`'; // !! LINE 12 
     try {   
      $sql = sprintf('SELECT %s FROM members WHERE id = ?', $fields);   
      $stmt = $db->prepare($sql); 
      $stmt->execute(array($user_id)); 
      $data = $stmt->fetch(PDO::FETCH_ASSOC);   
      return $data;   
     } catch(PDOException $e) { 
      die($e->getMessage()); 
     } 
    } 
} 

это где я вызываю функцию

<?php 
session_start(); 
require 'database/connect_db.php'; 
require 'functions/users.php'; 

if (signedIn() === true) { 
    $session_id = $_SESSION['id']; 
    $user_data = user_data($session_id, $db, 'email', 'password', 'role', 'name', 'company', 'title', 'phone', 'address', 'city', 'zip', 'state', 'ext', 'pic'); 
    echo $user_data['name']; 
} 

?> 

это моя ошибка

Catchable fatal error: Object of class PDO could not be converted to string in C:\xampp\htdocs\core\functions\users.php on line 12 

Так более конкретно эта линия, как прокомментировал в функция выше

$fields = '`' . implode('`, `', $func_get_args) . '`'; 

Я не понимаю, почему эта строка вызывает эту ошибку. Я также не знаю, как это исправить. Любая помощь приветствуется.

+1

Я думаю, что 'unset ($ func_get_args [0]);' должно быть 'unset ($ func_get_args [1]);'. Вы 'unset'ting $ user_id вместо $ db – Mike

+0

@Mike вы были правы –

ответ

1

func_get_args() возвращает все аргументы функции. Вы отключаете() 0-й элемент, но у вас есть два элемента, которые необходимо удалить с начала args. Ниже показан пример использования array_slice() для начала с элемента 2.

Кроме того, ваша функция обладает вопиющей уязвимостью SQL-инъекции, интерполируя список имен столбцов непосредственно в ваш список выбора SQL. Вы должны вносить белый список ввода в список всех столбцов таблицы пользователей, чтобы убедиться, что вход не содержит чего-то, чего вы не ожидаете.

function user_data($user_id, PDO $db) { 
    // hardcoded list of the columns in the users table; use this as a whitelist 
    $all_users_columns = array('first_name', 'last_name', 'email', /* etc. */); 

    $columns = array_intersect(array_slice(func_get_args(), 2), 
           $all_users_columns); 

    if($columns) { 
     $column_list = implode(",", 
      array_map(function($col) { return "`$col`"; }, $columns)); 
     try {   
      $sql = sprintf('select %s from users where user_id = ?', $column_list);   
      $stmt = $db->prepare($sql); 
      $stmt->execute(array((int)$userid)); 
      $data = $stmt->fetch(PDO::FETCH_ASSOC);   
      return $data;   
     } catch(PDOException $e) { 
      die($e->getMessage()); 
     } 
    } 
} 
+0

+ 1 спасибо за указание на уязвимость. Я не думал об этом –

+0

Ответ принят, так как он является самым полным –

+0

Anonymous downvoter: можете ли вы объяснить свое возражение на этот ответ? Возможно, я смогу его улучшить. –

2

Ваш последний аргумент функции PDO, вы должны удалить его из списка полей с помощью array_pop.

function user_data($user_id, $db) { 
    $data = array(); 
    $user_id = (int)$user_id; 

    $func_num_args = func_num_args(); 
    $func_get_args = func_get_args(); 

    array_pop($func_get_args);  //<----------------------- line added 

    if($func_num_args > 1) { 
    // unset($func_get_args[0]);  // <---------------------- line commented 
     $fields = '`' . implode('`, `', $func_get_args) . '`'; // !! LINE 12 
     try {   
      $sql = sprintf('select %s from users where user_id = ?', $fields);   
      $stmt = $dbh->prepare($sql); 
      $stmt->execute(array($userid)); 
      $data = $stmt->fetch(PDO::FETCH_ASSOC);   
      return $data;   
     } catch(PDOException $e) { 
      die($e->getMessage()); 
     } 
    } 
} 
3

Проблема заключается в том, когда вы используете func_get_args он пытается форматировать $db аргумент, чтобы строки.

Я переработан код немного, чтобы вместо того, чтобы передать массив для 3-го аргумента

function user_data($user_id, $db, $select = array()) { 
    if (count($select)) $fields = "`".implode('`, `', $select)."`"; 
    else $fields = "*"; 

    try { 
     $stmt = $db->prepare("SELECT {$fields} FROM members WHERE id=?");    
     $stmt->execute(array($user_id)); 
     return $stmt->fetch(PDO::FETCH_ASSOC); 
    } catch(PDOException $e) { 
     die($e->getMessage()); 
    } 
} 

, как вы могли бы назвать эту функцию теперь так:

$user_array = array('email', 'password', 'role', 'name', 'company', 'title', 'phone', 'address', 'city', 'zip', 'state', 'ext', 'pic'); 
$user_data = user_data($session_id, $db, $user_array); 

Надеемся, что это работает для вашего симпатия!

+0

, что меня беспокоит, так это то, что вы исправили мой запрос к тому, каким он должен быть. В примере у меня есть «ОТ пользователей», и моя таблица на самом деле является «членами». Это жуткий –

+0

Я начал работать над вашим предыдущим вопросом, который был удален, я думаю, и код все еще сохраняется. Ха-ха, может быть, немного жутко. –

+0

@i_me_mine Если это сработало, для вас, пожалуйста, дайте мне знать. –

Смежные вопросы