PHP 中非对象上的函数 fetch()

发布于 2024-10-11 11:23:26 字数 5178 浏览 10 评论 0原文

我有这个网址,

http://webworks.net/ww.incs/forgotten-password-verification.php?verification_code=974bf747124c69f12ae3b36afcaccc68&[email protected]&redirect=/ww.admin/index.php

这给出了以下错误。

Fatal error: Call to a member function fetch() on a non-object in
/var/www/webworks/ww.incs/basics.php on line 23 
Call Stack: 0.0005 338372 1. {main}() 
/var/www/webworks/ww.incs/forgotten-password-verification.php:
0 0.0020 363796 2. dbRow() 
/var/www/webworks/ww.incs/forgotten-password-verification.php:18

忘记密码的verification.php

require 'login-libs.php';

login_check_is_email_provided();

// check that a verification code was provided
if(
 !isset($_REQUEST['verification_code']) || $_REQUEST['verification_code']==''
){
 login_redirect($url,'novalidation');
}

// check that the email/verification code combination matches a row in the user table
// $password=md5($_REQUEST['email'].'|'.$_REQUEST['password']);
$r=dbRow('select * from user_accounts where
 email="'.addslashes($_REQUEST['email']).'" and
 verification_code="'.$_REQUEST['verification_code'].'" and active'
);
if($r==false){
 login_redirect($url,'validationfailed');
}

// success! set the session variable, then redirect
$_SESSION['userdata']=$r;
$groups=json_decode($r['groups']);
$_SESSION['userdata']['groups']=array();
foreach($groups as $g)$_SESSION['userdata']['groups'][$g]=true;
if($r['extras']=='')$r['extras']='[]';
$_SESSION['userdata']['extras']=json_decode($r['extras']);

login_redirect($url);

和login-libs,

require 'basics.php';

$url='/';
$err=0;

function login_redirect($url,$msg='success'){
 if($msg)$url.='?login_msg='.$msg;
 header('Location: '.$url);
 echo '<a href="'.htmlspecialchars($url).'">redirect</a>';
 exit;
}

// set up the redirect
if(isset($_REQUEST['redirect'])){
 $url=preg_replace('/[\?\&].*/','',$_REQUEST['redirect']);
 if($url=='')$url='/';
}

// check that the email address is provided and valid
function login_check_is_email_provided(){
 if(
  !isset($_REQUEST['email']) || $_REQUEST['email']==''
  || !filter_var($_REQUEST['email'], FILTER_VALIDATE_EMAIL)
 ){
  login_redirect($GLOBALS['url'],'noemail');
 }
}

// check that the captcha is provided
function login_check_is_captcha_provided(){
 if(
   !isset($_REQUEST["recaptcha_challenge_field"]) || $_REQUEST["recaptcha_challenge_field"]==''
  || !isset($_REQUEST["recaptcha_response_field"]) || $_REQUEST["recaptcha_response_field"]==''
 ){
  login_redirect($GLOBALS['url'],'nocaptcha');
 }
}

// check that the captcha is valid
function login_check_is_captcha_valid(){
 require 'recaptcha.php';
 $resp=recaptcha_check_answer(
  RECAPTCHA_PRIVATE,
  $_SERVER["REMOTE_ADDR"],
  $_REQUEST["recaptcha_challenge_field"],
  $_REQUEST["recaptcha_response_field"]
 );
 if(!$resp->is_valid){
  login_redirect($GLOBALS['url'],'invalidcaptcha');
 }
}

basics.php是一样的,

session_start();
function __autoload($name) {
 require $name . '.php';
}
function dbInit(){
 if(isset($GLOBALS['db']))return $GLOBALS['db'];
 global $DBVARS;
 $db=new PDO('mysql:host='.$DBVARS['hostname'].';dbname='.$DBVARS['db_name'],$DBVARS['username'],$DBVARS['password']);
 $db->query('SET NAMES utf8');
 $db->num_queries=0;
 $GLOBALS['db']=$db;
 return $db;
}
function dbQuery($query){
 $db=dbInit();
 $q=$db->query($query);
 $db->num_queries++;
 return $q;
}
function dbRow($query) {
 $q = dbQuery($query);
 return $q->fetch(PDO::FETCH_ASSOC);
}
define('SCRIPTBASE', $_SERVER['DOCUMENT_ROOT'] . '/');
require SCRIPTBASE . '.private/config.php';
if(!defined('CONFIG_FILE'))define('CONFIG_FILE',SCRIPTBASE.'.private/config.php');
set_include_path(SCRIPTBASE.'ww.php_classes'.PATH_SEPARATOR.get_include_path());

我不知道如何解决这个问题。

我的数据库:

CREATE TABLE IF NOT EXISTS `user_accounts` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `email` text,
  `password` char(32) DEFAULT NULL,
  `active` tinyint(4) DEFAULT '0',
  `groups` text,
  `activation_key` varchar(32) DEFAULT NULL,
  `extras` text,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;

INSERT INTO `user_accounts` (`id`, `email`, `password`, `active`, `groups`, `activation_key`, `extras`) VALUES
(2, '[email protected]', '6d24dde9d56b9eab99a303a713df2891', 1, '["_superadministrators"]', '5d50e39420127d0bab44a56612f2d89b', NULL),
(3, '[email protected]', 'e83052ab33df32b94da18f6ff2353e94', 1, '[]', NULL, NULL),
(9, '[email protected]', '9ca3eee3c43384a575eb746eeae0f279', 1, '["_superadministrators"]', '974bf747124c69f12ae3b36afcaccc68', NULL);

I have this url,

http://webworks.net/ww.incs/forgotten-password-verification.php?verification_code=974bf747124c69f12ae3b36afcaccc68&[email protected]&redirect=/ww.admin/index.php

And this gives the following error.

Fatal error: Call to a member function fetch() on a non-object in
/var/www/webworks/ww.incs/basics.php on line 23 
Call Stack: 0.0005 338372 1. {main}() 
/var/www/webworks/ww.incs/forgotten-password-verification.php:
0 0.0020 363796 2. dbRow() 
/var/www/webworks/ww.incs/forgotten-password-verification.php:18

The forgotten-password-verification.php

require 'login-libs.php';

login_check_is_email_provided();

// check that a verification code was provided
if(
 !isset($_REQUEST['verification_code']) || $_REQUEST['verification_code']==''
){
 login_redirect($url,'novalidation');
}

// check that the email/verification code combination matches a row in the user table
// $password=md5($_REQUEST['email'].'|'.$_REQUEST['password']);
$r=dbRow('select * from user_accounts where
 email="'.addslashes($_REQUEST['email']).'" and
 verification_code="'.$_REQUEST['verification_code'].'" and active'
);
if($r==false){
 login_redirect($url,'validationfailed');
}

// success! set the session variable, then redirect
$_SESSION['userdata']=$r;
$groups=json_decode($r['groups']);
$_SESSION['userdata']['groups']=array();
foreach($groups as $g)$_SESSION['userdata']['groups'][$g]=true;
if($r['extras']=='')$r['extras']='[]';
$_SESSION['userdata']['extras']=json_decode($r['extras']);

login_redirect($url);

And login-libs,

require 'basics.php';

$url='/';
$err=0;

function login_redirect($url,$msg='success'){
 if($msg)$url.='?login_msg='.$msg;
 header('Location: '.$url);
 echo '<a href="'.htmlspecialchars($url).'">redirect</a>';
 exit;
}

// set up the redirect
if(isset($_REQUEST['redirect'])){
 $url=preg_replace('/[\?\&].*/','',$_REQUEST['redirect']);
 if($url=='')$url='/';
}

// check that the email address is provided and valid
function login_check_is_email_provided(){
 if(
  !isset($_REQUEST['email']) || $_REQUEST['email']==''
  || !filter_var($_REQUEST['email'], FILTER_VALIDATE_EMAIL)
 ){
  login_redirect($GLOBALS['url'],'noemail');
 }
}

// check that the captcha is provided
function login_check_is_captcha_provided(){
 if(
   !isset($_REQUEST["recaptcha_challenge_field"]) || $_REQUEST["recaptcha_challenge_field"]==''
  || !isset($_REQUEST["recaptcha_response_field"]) || $_REQUEST["recaptcha_response_field"]==''
 ){
  login_redirect($GLOBALS['url'],'nocaptcha');
 }
}

// check that the captcha is valid
function login_check_is_captcha_valid(){
 require 'recaptcha.php';
 $resp=recaptcha_check_answer(
  RECAPTCHA_PRIVATE,
  $_SERVER["REMOTE_ADDR"],
  $_REQUEST["recaptcha_challenge_field"],
  $_REQUEST["recaptcha_response_field"]
 );
 if(!$resp->is_valid){
  login_redirect($GLOBALS['url'],'invalidcaptcha');
 }
}

basics.php is,

session_start();
function __autoload($name) {
 require $name . '.php';
}
function dbInit(){
 if(isset($GLOBALS['db']))return $GLOBALS['db'];
 global $DBVARS;
 $db=new PDO('mysql:host='.$DBVARS['hostname'].';dbname='.$DBVARS['db_name'],$DBVARS['username'],$DBVARS['password']);
 $db->query('SET NAMES utf8');
 $db->num_queries=0;
 $GLOBALS['db']=$db;
 return $db;
}
function dbQuery($query){
 $db=dbInit();
 $q=$db->query($query);
 $db->num_queries++;
 return $q;
}
function dbRow($query) {
 $q = dbQuery($query);
 return $q->fetch(PDO::FETCH_ASSOC);
}
define('SCRIPTBASE', $_SERVER['DOCUMENT_ROOT'] . '/');
require SCRIPTBASE . '.private/config.php';
if(!defined('CONFIG_FILE'))define('CONFIG_FILE',SCRIPTBASE.'.private/config.php');
set_include_path(SCRIPTBASE.'ww.php_classes'.PATH_SEPARATOR.get_include_path());

I am not sure how to solve the problem.

My db:

CREATE TABLE IF NOT EXISTS `user_accounts` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `email` text,
  `password` char(32) DEFAULT NULL,
  `active` tinyint(4) DEFAULT '0',
  `groups` text,
  `activation_key` varchar(32) DEFAULT NULL,
  `extras` text,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;

INSERT INTO `user_accounts` (`id`, `email`, `password`, `active`, `groups`, `activation_key`, `extras`) VALUES
(2, '[email protected]', '6d24dde9d56b9eab99a303a713df2891', 1, '["_superadministrators"]', '5d50e39420127d0bab44a56612f2d89b', NULL),
(3, '[email protected]', 'e83052ab33df32b94da18f6ff2353e94', 1, '[]', NULL, NULL),
(9, '[email protected]', '9ca3eee3c43384a575eb746eeae0f279', 1, '["_superadministrators"]', '974bf747124c69f12ae3b36afcaccc68', NULL);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怀里藏娇 2024-10-18 11:23:26

我相信答案是这样的:

user_accounts:

    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `email` text,
    `password` char(32) DEFAULT NULL,
    `active` tinyint(4) DEFAULT '0',
    `groups` text,
    `activation_key` varchar(32) DEFAULT NULL,
    `extras` text,
    PRIMARY KEY (`id`)

'forgotten-password-verification.php':

    // check that the email/verification code combination matches a row in the user table
    // $password=md5($_REQUEST['email'].'|'.$_REQUEST['password']);
    $r=dbRow('select * from user_accounts where
    email="'.addslashes($_REQUEST['email']).'" and
    verification_code="'.$_REQUEST['verification_code'].'" and active'
    );

其中 verification_code 不是 的有效部分>用户帐户
改变它,它应该可以工作;)

The answer is, I believe, in this:

the table user_accounts:

    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `email` text,
    `password` char(32) DEFAULT NULL,
    `active` tinyint(4) DEFAULT '0',
    `groups` text,
    `activation_key` varchar(32) DEFAULT NULL,
    `extras` text,
    PRIMARY KEY (`id`)

and

the 'forgotten-password-verification.php':

    // check that the email/verification code combination matches a row in the user table
    // $password=md5($_REQUEST['email'].'|'.$_REQUEST['password']);
    $r=dbRow('select * from user_accounts where
    email="'.addslashes($_REQUEST['email']).'" and
    verification_code="'.$_REQUEST['verification_code'].'" and active'
    );

where verification_code is not a valid part of user_accounts.
Change it and it should work ;)

蓝咒 2024-10-18 11:23:26

basics.php 的第 23 行可能是:

return $q->fetch(PDO::FETCH_ASSOC);

这意味着 $q 不是您期望的对象(看起来像 PDOStatement)。显然,它是从dbQuery函数返回的,该函数返回PDO::query的结果。 PDO::query 将在成功时返回 PDOStatement,在错误时返回 FALSE。

这说明你的查询有误。最有可能的是这个:

$r=dbRow('select * from user_accounts where
 email="'.addslashes($_REQUEST['email']).'" and
 verification_code="'.$_REQUEST['verification_code'].'" and active'
);

问题可能是你的查询的结尾,它看起来不像有效的 SQL:

and active

另外,由于你使用的是 PDO,你应该利用准备好的语句,因为你的代码实际上对 SQL 注入开放。 addslashes 不是转义数据库参数的正确机制,除非您知道自己在做什么,否则不应使用 $_REQUEST。您应该直接使用 $_GET$_POST$_COOKIE

为了保护查询的安全,请使用准备好的语句并检查返回值:

function dbQuery($query, array $params = array()){
 $db=dbInit();
 $q=$db->prepare($query); // use prepare() instead of query()
 $q->execute($params);    // automatically bind the parameters with execute()
 $db->num_queries++;
 return $q;
}
function dbRow($query, array $params = array()) {
 $q = dbQuery($query, $params);
 if (!$q) {
    // check for errors
    throw new Exception('A database error has occured!');
 }
 return $q->fetch(PDO::FETCH_ASSOC);
}

然后只需执行以下操作:

$r=dbRow('select * from user_accounts where email=? and verification_code=?',
   array($_GET['email'], $_GET['verification_code'])
);

Line 23 of basics.php is probably:

return $q->fetch(PDO::FETCH_ASSOC);

This means that $q is not the object you expected it to be (seems like a PDOStatement). Apparently, it is returned from the dbQuery function, which returns the result of PDO::query. PDO::query will return a PDOStatement on success, or FALSE on error.

It means that you query is erroneous. Most likely this one:

$r=dbRow('select * from user_accounts where
 email="'.addslashes($_REQUEST['email']).'" and
 verification_code="'.$_REQUEST['verification_code'].'" and active'
);

The problem is probably the end of your query, which does not look like valid SQL:

and active

Also, since you are using PDO, you should take advantage of prepared statements, since your code is actually open to SQL injection. addslashes is not a proper mechanism for escaping database parameters, and you should not use $_REQUEST unless you know what you are doing. You should use $_GET, $_POST or $_COOKIE directly.

For your securing your queries, use prepared statements, and check the return values:

function dbQuery($query, array $params = array()){
 $db=dbInit();
 $q=$db->prepare($query); // use prepare() instead of query()
 $q->execute($params);    // automatically bind the parameters with execute()
 $db->num_queries++;
 return $q;
}
function dbRow($query, array $params = array()) {
 $q = dbQuery($query, $params);
 if (!$q) {
    // check for errors
    throw new Exception('A database error has occured!');
 }
 return $q->fetch(PDO::FETCH_ASSOC);
}

Then just do:

$r=dbRow('select * from user_accounts where email=? and verification_code=?',
   array($_GET['email'], $_GET['verification_code'])
);
高跟鞋的旋律 2024-10-18 11:23:26

password_reminder.php 中存在问题。

它使用的是 activation_code,而不是 verificatio_code

There is a problem in password_reminder.php.

In stead of verificatio_code, it was using activation_code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文