2011-01-02 2 views
1

У меня есть следующее исключение Caught exception: The supplied parameters to Zend_Auth_Adapter_DbTable failed to produce a valid sql statement, please check table and column names for validity. У меня есть google и проверка моего кода снова и снова, но я не нашел решения. Имена таблиц и столбцов верны.Введенные параметры Zend_Auth_Adapter_DbTable не привели к действительным операторам sql

Раздел, вызывающий эту проблему, составляет $result = $auth->authenticate($authAdapter);. Infact весь код контроллера находится ниже:

class AuthenticationController extends Zend_Controller_Action 
{ 
public function init() 
{ 
    $uri = $this->_request->getPathInfo(); 

    $activenav = $this->view->navigation()->findByUri($uri); 
    $activenav->active = true; 
} 

public function indexAction() 
{ 
    // action body 
} 

public function loginAction() 
{ 

    if(Zend_Auth::getInstance()->hasIdentity()) 
    { 
     $this->_redirect('index/index'); 
    } 

    $request = $this->getRequest(); 
    $form = new Application_Form_LoginForm(); 
    if($request->isPost()) 
    { 
     if($form->isValid($this->_request->getPost())) 
     { 

      $authAdapter = $this->getAuthAdapter(); 

      $username = $form->getValue('username'); 
      $password = $form->getValue('password'); 

      $authAdapter->setIdentity($username) 
         ->setCredential($password); 

      $auth = Zend_Auth::getInstance(); 

      try 
      { 
       $result = $auth->authenticate($authAdapter); 
      } 
      catch (Exception $e) 
      { 
       echo 'Caught exception: ', $e->getMessage(), "\n"; 
      } 

       if ($result->isValid()) 
       { 
        $identity = $authAdapter->getResultRowObject(); 
        $authstorage = $auth->getStorage(); 
        $authstorage->write($identity); 

        $this->_redirect('index/index'); 
       } 
       else 
       { 
        $this->view->errorMessage = "User name or password is wrong"; 
       } 
      } 
     } 

    $this->view->form = $form; 


} 

public function logoutAction() 
{ 
    Zend_Auth::getInstance()->clearIdentity(); 
    $this->_redirect('index/index'); 
} 

private function getAuthAdapter() 
{ 
    $authAdapter = new Zend_Auth_Adapter_DbTable(Zend_Db_Table::getDefaultAdapter()); 
    $authAdapter->setTableName('users') 
       ->setIdentityColumn('username') 
       ->setCredentialColumn('password') 
       ->setCredentialTreatment('SHA1(CONCAT(?,salt))'); 

    return $authAdapter; 
} 
} 

Я застрял на этом в течение нескольких дней, и теперь его сводит меня с ума. BTW Как я могу эхо из реального sql, который генерируется? Спасибо всем

ответ

3

Это зависит от версии MySQL, как описано выше. Следуя документации MySQL для версии 5.5:

«Если приложение хранит значения от функции, такой как MD5() или SHA1(), которая возвращает строку шестнадцатеричных цифр, более эффективное хранилище и сравнения могут быть получены путем преобразования шестнадцатеричного представления к двоичному с использованием UNHEX() и сохранению результата в столбце BINARY (N). Каждая пара шестнадцатеричных цифр требует одного байта в двоичной форме, поэтому значение N зависит от длины шестнадцатеричной строки. N равно 16 для MD5() и 20 для значения SHA1(). "

Таким образом, вместо понижения версии MySQL, вы можете сделать следующее:

  • изменить тип столбца 'пароль' из VARCHAR (32) в бинарном (16)
  • оных 'UNHEX()' функция MySQL на ваш запрос MySQL в ZF коде, например:
$adapter = new Zend_Auth_Adapter_DbTable(
    $db, 
    'user', 
    'login', 
    'password', 
    'UNHEX(MD5(CONCAT(?, passwordSalt)))' 
); 

Он хорошо работает в моем случае.

Edit - Если ваш пароль соль также хранится в двоичном столбце (например, если он тоже был шестнадцатеричная строка генерируется с помощью функции SHA1), то последний параметр Zend_Auth_Adapter_DbTable должен быть: «UNHEX (SHA1 (CONCAT (?, LOWER (HEX (соль))))) ' Итак, мы преобразуем соль обратно в строчную шестую строку перед конкатенацией с паролем.HEX() возвращает соль в верхнем регистре, поэтому вы можете просто опустить вызов LOWER(), если ваша соль была первоначально заглавной, прежде чем вы ее сохранили с помощью UNHEX().

+0

Casterama, спасибо за эту информацию. Я больше не работаю над этим проектом, но в следующий раз я обязательно использую маршрут UNHEX(). :) – Napoleon

+0

могу ли я просто изменить тип данных на двоичный, даже если моя таблица пользователя уже заполнена строками? не нужно ли мне повторно вставлять в качестве двоичного кода, поэтому нужно изменить пароль для каждого пользователя, который нужно вставить? – binnyb

3

Хорошо, так что я должен все осознавать, что этот ответ запатентован и лицензирован под одним из этих линий, что означает, что вы даже не можете прочитать или придумать похожий ответ (вы знаете Я шучу правильно?). Хорошо нормально до точки.

Через 3 дня я наткнулся на решение. Странная причина, но она устранила мою проблему. Так что все не работало, и никто не ответил на мой вопрос, поэтому я завладел этой новой книгой zend, которую я купил, чтобы просто попытаться отвлечься от проблемы. Дальнейшее отвлечение было для загрузки в Linux, а не из окон (я знаю, что с двойной загрузкой).

В Linux я решил создать виртуальный хост для проблемного проекта и просто попробовать его запустить. К моему supprise оно бежит без проблем. Я смог войти в систему. Затем я взглянул на phpmyadmin и увидел, что я версия mysql 5.1, где, как и в настройках моих вдов, - 5.5. Поэтому я подумал, почему бы не понизить mysql в окнах от 5.5 до 5.1.

Так что я сделал et viola, моя проблема исчезла. Я не знаю, что сделали люди в mysql, но похоже, что версия 5.5 может иметь проблемы с SHA1. Не уверен, что это относится к другим хеш-функциям. Может быть, кто-то подтвердит это подозрение?

+1

Я считаю, что вы правы, я выгляжу как SHA2. Я просто столкнулся с той же проблемой, что и вы. Спасибо тебе за это. – Bodman

0

Я решил это, как показано ниже:

1) ВИМ /etc/php.ini

error_reporting = E_ALL & ~E_NOTICE 
; which actually disable the notice errrors in log files too 

2) Затем я установил PHP и другие пакеты, например, как показано ниже, где он работает, а затем добавил пропавшие пакеты на главный сервер, и он работает.

# yum list installed php* 
Loaded plugins: auto-update-debuginfo, langpacks, presto, refresh-packagekit 
Installed Packages 
php.i686                5.3.10-1.fc15       @updates 
php-Smarty.noarch              2.6.26-2.fc15       @fedora 
php-ZendFramework.noarch            1.11.10-1.fc15      @updates 
php-ZendFramework-Cache-Backend-Apc.noarch        1.11.10-1.fc15      @updates 
php-ZendFramework-Cache-Backend-Memcached.noarch      1.11.10-1.fc15      @updates 
php-ZendFramework-Services.noarch          1.11.10-1.fc15      @updates 
php-ZendFramework-demos.noarch           1.11.10-1.fc15      @updates 
php-ZendFramework-extras.noarch           1.11.10-1.fc15      @updates 
php-bcmath.i686               5.3.10-1.fc15       @updates 
php-cli.i686               5.3.10-1.fc15       @updates 
php-common.i686               5.3.10-1.fc15       @updates 
php-devel.i686               5.3.10-1.fc15       @updates 
php-gd.i686                5.3.10-1.fc15       @updates 
php-mbstring.i686              5.3.10-1.fc15       @updates 
php-mcrypt.i686               5.3.10-1.fc15       @updates 
php-mysql.i686               5.3.10-1.fc15       @updates 
php-pdo.i686               5.3.10-1.fc15       @updates 
php-pear.noarch               1:1.9.4-1.fc15      @updates 
php-pear-Cache-Lite.noarch            1.7.11-1.fc15       @updates 
php-pear-XML-Beautifier.noarch           1.2.2-2.fc15       @fedora 
php-pear-XML-Parser.noarch            1.3.4-2.fc15       @fedora 
php-pear-XML-RPC2.noarch            1.0.6-1.fc15       @fedora 
php-pear-XML-RSS.noarch             1.0.2-1.fc15       @updates 
php-pear-XML-Serializer.noarch           0.20.2-2.fc15       @fedora 
php-pecl-apc.i686              3.1.9-1.fc15       @updates 
php-pecl-apc-devel.i686             3.1.9-1.fc15       @updates 
php-pecl-memcache.i686             3.0.5-3.fc15       @fedora 
php-php-gettext.noarch             1.0.11-3.fc15       @updates 
php-process.i686              5.3.10-1.fc15       @updates 
php-qt.i686                4.6.5-1.fc15       @updates 
php-qt-devel.i686              4.6.5-1.fc15       @updates 
php-snmp.i686               5.3.10-1.fc15       @updates 
php-soap.i686               5.3.10-1.fc15       @updates 
php-xml.i686               5.3.10-1.fc15       @updates 
phpMyAdmin.noarch              3.4.9-1.fc15       @updates 
3

Убедитесь, что параметры unicode 'utf-8' соответствуют ожиданиям вашего MySQL-сервера.

Другими словами, не устанавливайте кодировку как «utf-8» в файле application.ini, если ваш сервер не настроен для этого (как и по умолчанию). A ...

SET NAMES 'utf8' 

отправлено MySQL из ZF, которое вызывает ошибку.

Удаление кодировки 'utf-8' в application.ini разрешило это для меня.

+0

Бог спас меня. : D Спасибо @kervin – Nabin

0

Как уже ответил Кервин, эта ошибка возникает из-за несоответствия сортировки между php и mysql.

Вы можете либо прекратить использование utf8 как предложено в указанном выше растворе или вы можете изменить таблицу базы данных, чтобы использовать utf8. (Он работал для меня только после того, как я удалил данные внутри таблицы и повторно их.)

+1

Я удалил 'resources.db.charset =" utf8 "' в моем приложении.ini, но у меня все еще есть эта проблема. если я добавлю 'resources.db.params.charset =" latin1 ", ошибка исчезнет, ​​но в других местах я получаю данные, которые иногда получают кодирование. что я делаю! – binnyb

0

У меня была такая же ошибка, и я понял, что это вводит в заблуждение. В моем случае оказалось, что я подключался к неправильной базе данных по причинам, которые не стоит объяснять. То, что вы хотите сделать, это получить предыдущее исключение, которое вызвало Zend_Auth_Adapter_DbTable, чтобы выбросить исключение, которое вы упомянули. Ниже, как я достиг этого:

$adapter = $this->_getAuthAdapter(); 
    $adapter->setIdentity($values['username']); 
    $adapter->setCredential($values['password']); 

    $auth = \Zend_Auth::getInstance(); 
    try { 
     $result = $auth->authenticate($adapter); 

    } catch (\Zend_Auth_Adapter_Exception $ex) { 
     die($ex->getPrevious()->getMessage()); 
    } 

Таким образом, в конце концов, ответ не совсем:

SET NAMES 'utf8' 

Это действительно может быть любое количество вопросов. Лучше всего позволить MySQL рассказать вам, получив предыдущее исключение. Возможно, ответ будет связан с кодировкой символов. В моем случае это не так.

0
$dbAdapter = Zend_Db_Table::getDefaultAdapter(); 
    $authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter); 

    $version = $dbAdapter->getServerVersion(); 

    if (!is_null($version)) 
    { 
     if (version_compare($version, '5.5', '>=')){ 
      $credentialTreatment = 'CAST(SHA1(CONCAT(?, salt)) AS CHAR) AND active = 1'; 
     }else{ 
      $credentialTreatment = 'SHA1(CONCAT(?, salt)'; 
     } 
    } 


    $authAdapter->setTableName('users') 
    ->setIdentityColumn('username') 
    ->setCredentialColumn('passwd') 
    ->setCredentialTreatment($credentialTreatment); 

    return $authAdapter; 

Пожалуйста, проверьте этот

По MySQL 5.5.3, возвращаемое значение является непарностью строки в наборе символов соединения. До 5.5.3 возвращаемое значение представляет собой двоичную строку; см. примечания в начале этого раздела об использовании значения в виде недвоичной строки.

Это работает для меня.

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