Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > PDO проблема


Автор: Veve 30.11.2009, 09:11
Привет, совсем замучался. Либо не высполся, либо уже вообще ничего не понимаю. 

Этот код работает правильно. Запрос выполняется.

Код

$sth=PDO::prepare("SELECT * FROM   users WHERE  login=:login and password=:password");

$this->bindParams['value'][':login']='worker';
$this->bindParams['value'][':password']='b61822e8357dcaff77eaaccf348d9134';

if (isset($this->bindParams))
               foreach ($this->bindParams['value'] as $key => $value)        
                    $sth->bindParam($key, $this->bindParams['value'][$key],2 );


А так уже не работает: 


Код

$sth=PDO::prepare("SELECT * FROM   users WHERE  login=:login and password=:password");

$this->bindParams['value'][':login']='worker';
$this->bindParams['value'][':password']='b61822e8357dcaff77eaaccf348d9134';

if (isset($this->bindParams))
               foreach ($this->bindParams['value'] as $key => $value)        
                    $sth->bindParam($key, $value,2 );



Что за хрень?



Автор: NewDima 30.11.2009, 10:25
дебаж. Поставь вместо $sth->bindParam var_dump

Автор: Simpliest 30.11.2009, 10:31
Осталось выяснить причем тут PDO и приведенный код.
Если не работает в другом месте.

Автор: Veve 30.11.2009, 13:50
Цитата

дебаж. Поставь вместо $sth->bindParam var_dump 


var_dump для $this->bindParams['value'][$key] и для $value
абсолютно идентичны

Цитата

Осталось выяснить причем тут PDO и приведенный код.
Если не работает в другом месте. 


В каком месте у тебя не работает? 

$sth->bindParam () это метод pdostatement`a  и туда передаются одинаковые значения, где по твоему ошибка? 

Автор: Simpliest 30.11.2009, 15:17
Цитата(Veve @  30.11.2009,  12:50 Найти цитируемый пост)

В каком месте у тебя не работает? 
...
где по твоему ошибка? 

Понятия не имею. Код ведь весь у тебя smile

Я просто знаю что
Цитата(Veve @  30.11.2009,  12:50 Найти цитируемый пост)
var_dump для $this->bindParams['value'][$key] и для $value
абсолютно идентичны


А значит ошибка не тут.

Автор: Veve 30.11.2009, 18:26
Дорогие коллеги, чтобы не быть единоличникам обладающим всем кодом, ниже привожу ВЕСЬ исходник. В надежде услышать хоть что-то более или менее вразумительное.

Код

<?php

$db = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$stmt=$db->prepare("SELECT * FROM   test WHERE  id=:id and name=:name");
$bindParams['value'][':id']='1';
$bindParams['value'][':name']='name1';
if (isset($bindParams))
               foreach ($bindParams['value'] as $key => $value)
               {
                   
                    $stmt->bindParam($key, $value,2 );
                   // $stmt->bindParam($key, $bindParams['value'][$key],2 );
               }

$stmt->execute();
$res=$stmt->fetchAll();
print_r($res);


?>


Также прикладываю sqlник для создание тестовой базы mysql:

Код

/*
SQLyog Enterprise - MySQL GUI v8.1 Beta1
MySQL - 5.1.37 : Database - test
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;

CREATE DATABASE /*!32312 IF NOT EXISTS*/`test` /*!40100 DEFAULT CHARACTER SET latin1 */;

USE `test`;

/*Table structure for table `test` */

DROP TABLE IF EXISTS `test`;

CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;




Автор: Simpliest 30.11.2009, 18:44
Цитата(Veve @  30.11.2009,  17:26 Найти цитируемый пост)
foreach ($bindParams['value'] as $key => $value)


Код

foreach ($bindParams['value'] as $key => &$value)


Вот тебе и весь секрет.

Добавлено через 1 минуту и 5 секунд
Заняло ровно 30с вместе с копированием скриптов smile

Автор: Veve 30.11.2009, 18:53
Спасибо,
Нельзя ли в более раскрытой форме объяснить почему так. 

Автор: Simpliest 30.11.2009, 19:03
Цитата(Veve @  30.11.2009,  17:53 Найти цитируемый пост)
Нельзя ли в более раскрытой форме объяснить почему так.  

Ммм. исходники надо смотреть.

Собственно натолкнуло меня на эту мысль то, что при биндинге привязывается не конкретное значение, а переменная! (точнее ссылка на значение)

Поэтому в первом случае ты использовал ссылку разных элементов массива!
А во втором случае одной и той же переменной. В его конце оно затиралось последним значением и во все плейсхолдеры шло именно оно.
Т.е. запрос получался как бы
Код

SELECT * FROM   test WHERE  id=name1 and name=name1

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)