2013-08-20 3 views
3

это мой текущий класс базы данных:Создание класса базы данных PHP PDO, проблемы с ООП

class Database { 

    private $db; 

    function Connect() { 
     $db_host = "localhost"; 
     $db_name = "database1"; 
     $db_user = "root"; 
     $db_pass = "root"; 
     try { 
      $this->db = new PDO("mysql:host=" . $db_host . ";dbname=" . $db_name, $db_user, $db_pass); 
     } catch(PDOException $e) { 
      die($e); 
     } 
    } 

    public function getColumn($tableName, $unknownColumnName, $columnOneName, $columnOneValue, $columnTwoName = "1", $columnTwoValue = "1") { 
     $stmt = $this->db->query("SELECT $tableName FROM $unknownColumnName WHERE $columnOneName='$columnOneValue' AND $columnTwoName='$columnTwoValue'"); 
     $results = $stmt->fetchAll(PDO::FETCH_ASSOC); 
     return $results[0][$unknownColumnName]; 
    } 
} 

Я пытаюсь запустить его, используя следующий код:

$db = new Database(); 
$db->Connect(); 
echo $db->getColumn("Sessions", "token", "uid", 1); 

И я получаю следующая ошибка:

PHP Fatal error: Call to a member function fetchAll() on a non-object in /Users/RETRACTED/RETRACTED/root/includes/Database.php on line 19

Любая идея, что случилось? Спасибо

+2

На стороне записки, я бы использовать подготовленные заявления PDO путем привязки а не включать их напрямую. Например, '-> prepare ('SELECT? FROM? WHERE ...') -> выполнить (func_get_args());'. –

+1

Спасибо Остин, я обязательно буду использовать подготовленные заявления в будущем. – User2013

+4

@AustinBrunkhorst Вы не можете использовать привязку параметров для идентификаторов БД (имена таблиц и столбцов), только значения – Phil

ответ

5
  1. Эта функция подвержена SQL-инъекции.
  2. Эта функция не позволит вам получить столбец, используя даже простейшее условие ИЛИ.
  3. Эта функция делает нечитаемую тарабарщину из почти естественного языка английского языка.

Посмотрите, вы даже испортили себе эту самую функцию. Как вы предполагаете, что он будет использоваться для ежедневного кодирования? На самом деле эта функция делает ваш опыт сложнее, чем с необработанным PDO - вам нужно изучить все новые синтаксисы, многочисленные исключения и исправления в последнюю минуту.

Пожалуйста, вернитесь к необработанному PDO!

Позвольте мне показать вам правильный путь

public function getColumn($sql, $params) 
{ 
    $stmt = $this->db->prepare($sql); 
    $stmt->execute($params); 
    return $stmt->fetchColumn(); 
} 

используется как этот

echo $db->getColumn("SELECT token FROM Sessions WHERE uid = ?", array(1)); 

Таким образом, вы будете иметь возможность использовать всю мощь SQLне ограничивается глупое подмножество, а также безопасность подготовленных заявлений, но сохраните свой код понятным.
При звонке по-прежнему в одной строке - это было ваше первоначальное (и очень правильное!) Намерение.

+3

Спасибо, само собой разумеется, что я новичок в PDO и, несмотря на то, что я благодарен за урок, который вы преподавали. – User2013

+11

-1 Извините, но использование такого рода подчеркиваний в сочетании с таким дерзким отношением просто не нужно. Мы все должны были начать в какой-то момент, и очень вероятно, что вам самим придется изучать новые вещи. –

+0

Вы не используете полную мощь SQL, если ограничиваете себя использованием функций класса, которые следуют только одному протоколу извлечения. Возможно, лучше вернуть '$ stmt' перед извлечением, а затем добавить любую функцию fetch к возвращаемому значению. Это также позволит вам создать функцию, которая будет работать и для запросов, не связанных с 'SELECT'. Во всяком случае, его цель состоит в том, чтобы избежать необходимости переписывать 'prepare()' и 'execute()'. –

1

это означает, что ваша переменная $ stmt не возвращает объект PDOStatement. ваш запрос терпит неудачу, поскольку PDO :: query возвращает PDOStatement или False при ошибке.

0

Использование fetch вместо fetchAll ..это будет легко в вашем случае

$results = $stmt->fetchAll(PDO::FETCH_ASSOC); 
return $results[0][$unknownColumnName]; 

Это будет

$results = $stmt->fetch(PDO::FETCH_ASSOC); 
return $results[$unknownColumnName]; 
Смежные вопросы