Mysql 提供给Zend_Auth_Adapter_DbTable的参数未能生成有效的sql语句

Mysql 提供给Zend_Auth_Adapter_DbTable的参数未能生成有效的sql语句,mysql,zend-framework,zend-auth,Mysql,Zend Framework,Zend Auth,我发现以下异常捕获到异常:提供给Zend_Auth_Adapter_DbTable的参数未能生成有效的sql语句,请检查表和列名的有效性。我已反复搜索和检查我的代码,但未找到解决方案。表名和列名都是正确的 导致此问题的代码部分是$result=$auth->authenticate($authAdapter)。事实上,整个控制器代码如下所示: class AuthenticationController extends Zend_Controller_Action { public functi

我发现以下异常
捕获到异常:提供给Zend_Auth_Adapter_DbTable的参数未能生成有效的sql语句,请检查表和列名的有效性。
我已反复搜索和检查我的代码,但未找到解决方案。表名和列名都是正确的

导致此问题的代码部分是
$result=$auth->authenticate($authAdapter)。事实上,整个控制器代码如下所示:

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;
}
}
我已经被困在这个问题上好几天了,这让我发疯。 顺便说一句,我如何回显正在生成的实际sql?
谢谢大家

好的,首先我需要让大家知道,这个答案已经获得专利和许可,这意味着你甚至无法阅读或得出类似的答案。(你知道我在开玩笑吧?)。好吧,好吧,说到点子上

三天后,我偶然发现了一个解决方案。一个奇怪的原因,但它解决了我的问题。所以一切都不顺利,也没有人回答我的问题,所以我买了这本新的zend书,试图分散我对这个问题的注意力。另一个干扰是引导到Linux而不是windows(你知道我是双引导)

在Linux中,我决定为这个有问题的项目创建一个虚拟主机,然后试着运行它。让我补充一下,它运行起来没有问题。我可以登录。然后我查看了phpmyadmin,发现mysql版本是5.1,widows设置中的版本是5.5。所以我想为什么不把windows中的mysql从5.5降级到5.1呢


所以我就把我的问题解决了。我不知道mysql的工作人员对它做了什么,但5.5版似乎与SHA1有问题。但不确定它是否适用于其他哈希函数。可能有人会证实这一怀疑吗?

好的,首先我需要让所有人都知道,这个答案已经获得了专利,并获得了许可,这意味着你甚至无法阅读或得出类似的答案。(你知道我在开玩笑吧?)。好吧,好吧,说到点子上

三天后,我偶然发现了一个解决方案。一个奇怪的原因,但它解决了我的问题。所以一切都不顺利,也没有人回答我的问题,所以我买了这本新的zend书,试图分散我对这个问题的注意力。另一个干扰是引导到Linux而不是windows(你知道我是双引导)

在Linux中,我决定为这个有问题的项目创建一个虚拟主机,然后试着运行它。让我补充一下,它运行起来没有问题。我可以登录。然后我查看了phpmyadmin,发现mysql版本是5.1,widows设置中的版本是5.5。所以我想为什么不把windows中的mysql从5.5降级到5.1呢


所以我就把我的问题解决了。我不知道mysql的工作人员对它做了什么,但5.5版似乎与SHA1有问题。但不确定它是否适用于其他哈希函数。可能有人会证实这一怀疑?

这取决于上述MySQL版本。5.5版的以下MySQL文档:

“如果应用程序存储来自返回十六进制数字字符串的函数(如MD5()或SHA1())的值,则可以通过使用UNHEX()将十六进制表示转换为二进制并将结果存储为二进制(N)来获得更有效的存储和比较。”列。每对十六进制数字需要一个二进制字节,因此N的值取决于十六进制字符串的长度。对于MD5()值,N为16,对于SHA1()值,N为20。”

因此,您可以按如下操作,而不是降级MySQL版本:

  • 将“密码”列的类型从varchar(32)更改为二进制(16)
  • 在ZF代码中将“UNHEX()”MySQL函数添加到MySQL查询中,例如:
$adapter=new Zend\u Auth\u adapter\u DbTable(
$db,
“用户”,
“登录”,
“密码”,
“UNHEX(MD5(CONCAT(?,passwordSalt))”
);
对我来说效果很好

编辑-- 如果密码salt也存储在二进制列中(例如,如果它也是通过SHA1函数生成的十六进制字符串),那么Zend_Auth_Adapter_DbTable的最后一个参数应该是: “UNHEX(SHA1(CONCAT(?,LOWER(HEX(salt)(()))))”
因此,在与密码连接之前,我们将salt转换回一个小写十六进制字符串。HEX()以大写形式返回salt,因此,如果salt在使用UNHEX()存储之前是大写的,则可以省略LOWER()调用。

它取决于上述MySQL版本。5.5版的以下MySQL文档:

“如果应用程序存储来自返回十六进制数字字符串的函数(如MD5()或SHA1())的值,则可以通过使用UNHEX()将十六进制表示转换为二进制并将结果存储为二进制(N)来获得更有效的存储和比较。”列。每对十六进制数字需要一个二进制字节,因此N的值取决于十六进制字符串的长度。对于MD5()值,N为16,对于SHA1()值,N为20。”

因此,您可以按如下操作,而不是降级MySQL版本:

  • 将“密码”列的类型从varchar(32)更改为二进制(16)
  • 在ZF代码中将“UNHEX()”MySQL函数添加到MySQL查询中,例如:
$adapter=new Zend\u Auth\u adapter\u DbTable(
$db,
“用户”,
“登录”,
“密码”,
“UNHEX(MD5(CONCAT(?,passwordSalt))”
);
对我来说效果很好

编辑-- 如果密码salt也存储在二进制列中(例如,如果它也是通过SHA1函数生成的十六进制字符串),那么Zend_Auth_Adapter_DbTable的最后一个参数应该是: “UNHEX(SHA1(CONCAT(?,LOWER(HEX(salt)(()))))” 因此,在与密码连接之前,我们将salt转换回一个小写十六进制字符串。HEX()以大写形式返回salt,因此可以省略t
error_reporting = E_ALL & ~E_NOTICE
; which actually disable the notice errrors in log files too
# 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
SET NAMES 'utf8'
    $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'
    $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;