функция fetch () для необъекта в PHP - PullRequest
0 голосов
/ 08 января 2011

У меня есть этот URL,

http://webworks.net/ww.incs/forgotten-password-verification.php?verification_code=974bf747124c69f12ae3b36afcaccc68&email=myemail@gmail.com&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

Forgotten-password-verify.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, 'bla@blabla.com', '6d24dde9d56b9eab99a303a713df2891', 1, '["_superadministrators"]', '5d50e39420127d0bab44a56612f2d89b', NULL),
(3, 'user@blabla.com', 'e83052ab33df32b94da18f6ff2353e94', 1, '[]', NULL, NULL),
(9, 'myemail@gmail.com', '9ca3eee3c43384a575eb746eeae0f279', 1, '["_superadministrators"]', '974bf747124c69f12ae3b36afcaccc68', NULL);

Ответы [ 3 ]

1 голос
/ 15 апреля 2012

Ответ, я полагаю, таков:

стол 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`)

и

the Forgotten-Password-verify.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 не является допустимой частью user_accounts. Измени его и оно должно работать;)

0 голосов
/ 13 января 2011

Проблема в password_reminder.php.

Вместо verificatio_code он использовал activation_code.

0 голосов
/ 08 января 2011

Строка 23 из basics.php, вероятно, равна:

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'])
);
...