PHP: как бы я использовал этот простой класс? - PullRequest
1 голос
/ 24 июля 2010

Я искал более «правильные» части кода для входа / выхода из системы и нашел этот код: http://snipplr.com/view/1079/auth/

Я получил два вопроса, которые мешают мне его использовать.1: Как бы я создал экземпляр класса и использовал его в своем скрипте? (Я знаю PHP, но по какой-то причине просто озадачен)2: есть следующие строки:

global $db;
$db->query("sql here...");

Как на самом деле это делает объект базы данных?Я думаю, может быть, мне следует создать объект типа $db = mysql_connect(...) вне сценария, а global вызывает его из-за пределов класса?

Если я знаю, как вызывать этот класс, другие будут казаться бризомэто действительно полезно для меня!

Ответы [ 3 ]

5 голосов
/ 24 июля 2010

Этот код опасен, вы не должны использовать его в его текущем состоянии.

  • Он слепо доверяет $_COOKIE и создает запросы SQL, используя конкатенацию строк, без правильного экранирования ввода. Вредоносные пользователи могут легко выполнить SQL-инъекцию в любом приложении, использующем этот класс.
  • Наличие ключевого слова var, наличие конструктора, использующего то же имя, что и у класса, и отсутствие ключевых слов управления доступом перед методами говорит о том, что код был написан для PHP4, а не PHP5. Это все еще будет работать, хотя

Обе эти проблемы решаемы. Сначала давайте ответим на ваши вопросы.

  1. Код, написанный @Delan Azabani, является хорошим примером использования класса.
  2. Код сбивает с толку. Сначала кажется, что код использует объект базы данных real вместо старых низкоуровневых функций, предоставляемых расширением mysql. Но затем он идет и вызывает функции из расширения mysql! Вероятно, это чья-то заказная оболочка. На самом деле код не создает объект базы данных, он просто ссылается на значение $db в глобальной области видимости, как вы подозреваете.

Вы упомянули, что используете расширение mysql. Я призываю вас пересмотреть и использовать вместо него PDO или mysqli . Мало того, что этот класс будет работать с обоими (хотя с некоторыми изменениями, чтобы уменьшить явную дыру в безопасности), но ваш собственный код будет лучше использовать более современные, более безопасные методы, используемые в PDO и mysqli.

Давайте исправим метод login, используя PDO.

public function login($username, $password) {
    global $db;
    $sth = $db->prepare("SELECT user_id FROM users WHERE username = ? AND password = ?");
    $sth->execute(array($username, $password));
    if($sth->rowCount() == 1) {
        $this->user_id = $sth->fetchColumn();
        ...

Давайте рассмотрим, что изменилось. Сначала мы добавили заполнители запросов , это вопросительные знаки. Метод prepare возвращает дескриптор оператора , с которым вы, вероятно, уже знакомы. Далее мы сообщаем подготовленному оператору, что он запускается сам, используя метод execute, передавая массив переменных. Переменные будут автоматически экранированными для вас и затем вставлены в запрос вместо заполнителей.

После выполнения запроса мы используем rowCount, чтобы получить количество совпадающих строк. Мы хотим ровно одного. Поскольку мы вытягиваем первый столбец первой строки, мы используем fetchColumn , чтобы получить только этот бит данных.

Остальная часть метода входа в систему в порядке.

Метод check требует аналогичного исправления.

public function check($username, $password) {
    global $db;
    $sth = $db->prepare("SELECT user_id, password FROM users WHERE username = ?");
    $sth->execute(array($username));
    if($sth->rowCount() == 1) {
        list($db_user_id, $db_password) = $sth->fetch(PDO::FETCH_NUM);
        if(md5($db_password . $this->salt) == $password) {
            $this->user_id = $db_user_id;
            ...

Еще раз, мы готовим запрос с заполнителями, затем выполняем с фактическими переменными. Опять же, мы хотим только один ряд, но на этот раз мы хотим, чтобы все подряд. Мы будем использовать PDO::FETCH_NUM, чтобы сообщить fetch, что нам нужен числовой индексированный массив, затем возьмем две результирующие записи в массиве и поместим их в $db_user_id и $db_password используя их там, где старый код называется mysql_result. PDO не позволяет выбирать разные столбцы из одной строки, используя fetchColumn.

Если вы хотите использовать вместо этого расширение mysqli, вам нужно проделать еще немного работы. Я надеюсь, что убедил вас использовать PDO вместо этого!

Остальная часть класса, да, достаточно. Обязательно измените переменную класса $domain в верхней части, чтобы она соответствовала вашему фактическому имени домена, она используется в файлах cookie.

1 голос
/ 24 июля 2010

global $db только позволяет глобальному указателю базы данных $db быть доступным из метода класса. Вам нужно создать базу данных, запустив mysql_connect и mysql_select_db. Весь класс находится в классе Auth, поэтому создайте экземпляр объекта Auth, прежде чем делать что-либо еще (ну, конечно, после подключения к базе данных).

Затем вы можете вызывать методы внутри вашего Auth объекта. Например, если форма входа в систему отправляется на login-post.php, вы можете иметь этот код внутри:

$m = new Auth();
if ($m -> login($_POST['u'], $_POST['p'])) {
    header('Location: /');
    exit;
} else {
    header('Location: login?wrong=1');
    exit;
}
0 голосов
/ 24 июля 2010

Похоже, что код, который вы разместили, предполагает, что у вас есть переменная, определенная в вашей глобальной области видимости, которая называется $ db и выглядит как класс-оболочка для собственного ресурса PHP MySQL.Так что да, вы должны создать $ db снаружи в глобальной области видимости (то есть не внутри класса), но он ожидает пользовательский класс.

Я немного искал, и похоже, что он использует ЭТОТ класс: http://snipplr.com/view/27966/class-db/

Он просит вас создать INI-файл с именем "crunksauce.ini" (я не шучу)в том же каталоге, что и исполняемый скрипт, и содержит переменные конфигурации.Файл конфигурации должен выглядеть следующим образом:

database = <your database name>
host = <your db host>
user = <your db user>
pass = <your db password>

После создания файла конфигурации вы можете создать объект db следующим образом:

$db = new Db();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...