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;