SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 27.10.2008 00:18:16

MaxRed
Участник
Зарегистрирован: 27.10.2008
Сообщений: 11

PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

Бьюсь вторые сутки, помогите разобраться.
Есть такой код


<?php
include('conf_test.php');
function add_f($h)
  {
   $mysqli=myDB::myDB_getobj();
   $stmt = $mysqli->prepare("CALL add_data(?)");
   $stmt->bind_param('s',$h);
   $stmt->execute();
   $stmt->bind_result($add);
   $stmt->fetch();
   $stmt->close();
   return $add;
  }
for ($i=0; $i<10; $i++)
echo add_f('3d2295c85e7a167'.$i);
?>
 

Цикл сделан просто для теста, что бы несколько раз выполнилось с разными параметрами.
Запускаю скрипт все отработало как нужно, жму F5, тоже все впорядке но если еще потыкать F5 то на какой то раз появится ошибка

Fatal error: Call to a member function bind_param() on a non-object in D:\locNet\UsbWebserver\Root\test\indext.php on line 7

Вот какого это все происходит?!?!??
Вот код conf_test.php


<?php
class myDB extends mysqli
{
 const DB_HOST = 'localhost';
 const DB_LOGIN ='root';
 const DB_PASS = '1111';
 const DB_NAME = '2';
 static private $mysqli_con=null;
 static function myDB_getobj()
  {
   if (self::$mysqli_con == NULL)
    {
     self::$mysqli_con = new myDB(self::DB_HOST,self::DB_LOGIN,self::DB_PASS,self::DB_NAME,3307);
    }
   return self::$mysqli_con;
  }
}
?>
 

Буду рад хоть какойто помощи.

Неактивен

 

#2 28.10.2008 03:15:39

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

Вам следует выполнять проверку на ошибку при выполнении    $stmt = $mysqli->prepare("CALL add_data(?)");
Тогда будет ясно в чем причина

Неактивен

 

#3 28.10.2008 09:24:54

MaxRed
Участник
Зарегистрирован: 27.10.2008
Сообщений: 11

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

В примерах из описания сделано так

if ($stmt = $mysqli->prepare("ЗАПРОС")) {

    $stmt->bind_param("s", $var);
    ....
Само описание ошибки говорит о том что такое возможно если ЗАПРОС не имеет смысла (неверный).
В моем случае запрос ведь верный (проверена и хранимка и вызов ее из PHP скрипта)
Я немогу понять почему она работает не всегда. Причем независимо от передаваемых параметров.
Делал уже вообще тупую хранимую процедуру
BEGIN
SELECT 1;
END;
Вызываю из скрипта, работает. Начинаю запускать снова и снова и на какой то раз вываливается ошибка. Почему? Почему 10 раз (условно) работает, а на 11 Fatal error:?

Неактивен

 

#4 28.10.2008 11:57:50

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

в примерах сказано про else?

else {
   printf("Errormessage: %s\n", $mysqli->error);
}

Без кода ошибки понять в чем причина трудно

Неактивен

 

#5 28.10.2008 15:01:40

MaxRed
Участник
Зарегистрирован: 27.10.2008
Сообщений: 11

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

Блин, вот что значит опыт... =/
Да, действительно в примерах не сказано про
else {
   printf("Errormessage: %s\n", $mysqli->error);
}
Но ведь это очевидно было сделать... а я... sad
Вобщем спасибо огромное за "намек" smile
Ошибка вот такая
Errormessage: Lost connection to MySQL server during query
Errormessage: MySQL server has gone away
...
и так 10 раз столько сколько идет цикл
...
Хоть и неясно чего вдруг не может соединится... хм. Но это уже что то. буду разбираться. Хотя может вы чего подсоветуете smile

Неактивен

 

#6 28.10.2008 15:15:43

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

Похоже, что mysql-сервер регулярно падает и перезапускается и это происходит во время запроса. Посмотрите логи сервера (в линукс  /var/log/mysqld.log ), в нем должна присутствовать ошибка.
Причины могут быть разные - памяти не хватает, не хватает места на диске, бага в движке.

Неактивен

 

#7 28.10.2008 15:34:50

MaxRed
Участник
Зарегистрирован: 27.10.2008
Сообщений: 11

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

Я использую локальный сервер (USBwebserver 7.0) будем разбираться с ним.
Спасибо вам огромное!!! Рад что нашел ваш сайт.
Так начало прояснятся.
Я ведь работаю под виндой... и у нее есть проблемы с количеством соединений. Видимо в этом и проблема.
Есть патч для исправления ситуации. Как посталю-попробую, отпишусь, вдруг еще кто попадется.

Отредактированно MaxRed (28.10.2008 16:05:41)

Неактивен

 

#8 29.10.2008 11:55:18

MaxRed
Участник
Зарегистрирован: 27.10.2008
Сообщений: 11

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

Патч не решил проблемы sad
Для тестов сделал вот так (вообще без своих классов)


$DB_HOST = 'localhost';
$DB_LOGIN ='root';
$DB_PASS = '555';
$DB_NAME = '2';
$mysqli = new mysqli($DB_HOST,$DB_LOGIN,$DB_PASS,$DB_NAME,3307);

for ($i=1; $i<100; $i++)
{
 if($stmt = $mysqli->prepare("CALL test_proc()"))
  {
   //$stmt->bind_param('s',$h);
   $stmt->execute();
   $stmt->bind_result($add);
   $stmt->fetch();
   $stmt->close();
   echo $add;
  }
 else
  {
   printf("Errormessage: %s\n", $mysqli->error);
   exit;
  }
}
$mysqli->close();
 

Код test_proc()
BEGIN
SELECT 1;
END
Бага осталась. sad

Отредактированно MaxRed (29.10.2008 14:39:59)

Неактивен

 

#9 29.10.2008 14:22:46

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

Посмотрите что в логах сервера

Неактивен

 

#10 29.10.2008 14:44:58

MaxRed
Участник
Зарегистрирован: 27.10.2008
Сообщений: 11

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

В логах мускула только это
081029 13:35:33 [Note] D:/UsbWebserver/Mysql/bin/mysqld-nt_usb.exe: ready for connections.
Version: '5.0.24a-community-nt'  socket: ''  port: 3306  MySQL Community Edition (GPL)
081029 13:36:51 [Note] D:/UsbWebserver/Mysql/bin/mysqld-nt_usb.exe: ready for connections.
Version: '5.0.24a-community-nt'  socket: ''  port: 3306  MySQL Community Edition (GPL)
В логах Апача ошибки функций библиотеки mysqli (ну ясное дело)
Неужели трабла в библиотеке sad
Дело в том что если сделать такой запрос $stmt = $mysqli->prepare("SELECT 1") , то баги никогда не возникает, а вот если вызываю хранимку то бага.
Блин, начинаю поглядывать в сторону файрберда... а нехочется то как...

Отредактированно MaxRed (29.10.2008 14:45:52)

Неактивен

 

#11 29.10.2008 15:56:56

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

То, что написано в логах свидетельствует о том, что mysql-сервер постоянно перезагружается. Поэтому дело не в апаче и не в скрипте, а в запросе, который выполняете. Выходит, что он валит сервер.

Неактивен

 

#12 29.10.2008 16:10:18

MaxRed
Участник
Зарегистрирован: 27.10.2008
Сообщений: 11

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

Да не, это я в это время ребутил сервер. Он стабилен.
Запрос валит... хм почему в этом то и вопрос, ведь запрос прост как бит - SELECT 1
Причем я ж говорю именно такая реакция если делаю через хранимую процедуру

Отредактированно MaxRed (29.10.2008 16:59:59)

Неактивен

 

#13 29.10.2008 16:21:13

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

Ясно, значит клиент не работает с хранимыми процедурами.

Неактивен

 

#14 29.10.2008 16:59:18

MaxRed
Участник
Зарегистрирован: 27.10.2008
Сообщений: 11

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

rgbeast написал:

Ясно, значит клиент не работает с хранимыми процедурами.

Есть ли другие возможности работать с хранимками из PHP кроме mysqli?

Неактивен

 

#15 29.10.2008 19:06:02

EugeneTM
Гуру
Зарегистрирован: 11.04.2008
Сообщений: 89

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

Нормально работает с ХП и MySQLi и PDO.

Просто разработчики в мануале мозги запудрили народу по их применению.

Поймите главное.
Хранимая процедура для клиента ТАКОЙ ЖЕ ЗАПРОС как и обычный SELECT , INSERT etc. Просто в запросе у вас CALL написано.

Забудьте про параметры out, биндовку и т.п.
Нафиг оно не надо.

На PDO что-то вроде. Навороты личные поубивал. Может не заработать.


<?PHP
class DB
{

private $connect = null;

private function getConnect() {
try {
    if (is_null($this->connect))
        $this->connect =new PDO('mysql:host=' . $this->host . ';dbname='. $this->dbname, $this->user,  $this->password, array(PDO::ATTR_PERSISTENT => true));
    return $this->connect;                
}
catch (PDOException $e) {
    throw new Exception("Не смогла :-(");
}
}

public function quote($string) {
    return $this->getConnect->quote($string);
}

public function runSQL($sql) {
try {
    return $this->getConnect->query($sql)->fetchAll (PDO::FETCH_ASSOC);
}
catch (PDOException $e) {
    throw new Exception("Не смогла :-(");
}
}

function dbMyCall($str) {
    $qStr = $this->quote($str);
    return $this->runSQL("call mySP( $qStr)");
}

}

$myBD = new DB();

$resultArray = $myBD->dbMyCall($str) ;
 


Сама процедура типа


DELIMITER $$

DROP PROCEDURE IF EXISTS `test`.`mySP`$$
CREATE DEFINER=`my`@`%` PROCEDURE  `test`.`mySP`(
   param varchar(10)
   )
BEGIN
SELECT * FROM mytable WHERE mytable.myfld = param;
END $$

DELIMITER ;

 


В PDO попроще все делать чем в MySQLi. Поддержка exception есть ну и т.п.
Поменьше подводных камней типа Out of Sync в MySQLi.

Отредактированно EugeneTM (29.10.2008 19:11:34)

Неактивен

 

#16 29.10.2008 20:58:00

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

Есть ли другие возможности работать с хранимками из PHP кроме mysqli?

Ну, вообще-то обычная функция есть: mysql_query(). Почему бы ей не пользоваться?

<?php

function mysql_q($sql_query) { // это маленькая функция для удобства, чтоб каждый раз не писать про вывод ошибок
    return mysql_query($sql_query) or die(mysql_error());
}

function add_f($h) {
    $add = '';
    mysql_q("PREPARE my_statement FROM 'CALL add_data(?)'");
    mysql_q("SET @a = $h");
    $sql = "EXECUTE my_statement USING @a";
    if ($result = mysql_q($sql) AND $row = mysql_fetch_row($result)) {
        $add = $row[0];
    }
    return $add;
}

?>


Только лучше все-таки, по возможности, построить код так, чтобы вынести PREPARE STATEMENT из цикла: PREPARED STATEMENT "разбирается" один раз при создании, затем для каждого вызова работает быстрее, а так получается, что оно после одного вызова будет удаляться (при создании PREPARED STATEMENT с именем уже существующего последнее удаляется).

Неактивен

 

#17 30.10.2008 05:38:58

EugeneTM
Гуру
Зарегистрирован: 11.04.2008
Сообщений: 89

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

А на кой тут вообще PREPARE?

Неактивен

 

#18 30.10.2008 08:42:17

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

Засчет того, что PREPARED STATEMENTS обрабатываются парсером один раз, при первом вызове, а не при каждом выполнении, они иногда работает быстрее, чем несколько отдельных обычных запросов.

Хотя из логики приводимого скрипта необходимость их использования не ясна.

Неактивен

 

#19 30.10.2008 10:13:52

EugeneTM
Гуру
Зарегистрирован: 11.04.2008
Сообщений: 89

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

Это понятно.

Но только если запрос выполнять.

Хранимую процедуру парсер уже прошел. Вызов ХП парсим? smile

Неактивен

 

#20 30.10.2008 10:44:04

MaxRed
Участник
Зарегистрирован: 27.10.2008
Сообщений: 11

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

Спасибо, уже хоть что то.
Дело не в цикле. Цикл был взят ДЛЯ ТЕСТОВ.
Просто я когда работал со своими реальными функциями, стали вываливаться неясные ошибки, я стал тестить и в итоге понял что НЕМОГУ вызвать хранимку и быть уверен что вызов пройдет без ошибок.
Спасибо за вот это
mysql_q("PREPARE my_statement FROM 'CALL add_data(?)'");
mysql_q("SET @a = $h");
$sql = "EXECUTE my_statement USING @a";
Незнал. Насклько я был знаком с работой с MySQL в ПХП думал что нельзя выполнять подготовку запросов и пользоваться хранимками используя старую библиотеку mysql. Знал что есть mysqli ну и началось.
Буду пробовать дальше уже опираясь на советы. Вообще есть подозрение на мой USBWebserver.
Я ведь тест уже урезал до предела smile


for ($i=1; $i<100; $i++)
{
 if($result = $mysqli->query("CALL test_proc()"))
  {
    echo $result->num_rows;
  }
 else
  {
   printf("Errormessage: %s\n", $mysqli->error);
   exit;
  }
}
$mysqli->close();
 

баги остались... вот поздозрение и пало на USBWebserver.

Отредактированно MaxRed (30.10.2008 10:48:06)

Неактивен

 

#21 30.10.2008 11:00:54

EugeneTM
Гуру
Зарегистрирован: 11.04.2008
Сообщений: 89

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

А зачем готовить вызов хранимой процедуры?

Кто нибудь сможет ответить?

Неактивен

 

#22 30.10.2008 11:53:36

MaxRed
Участник
Зарегистрирован: 27.10.2008
Сообщений: 11

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

EugeneTM написал:

А зачем готовить вызов хранимой процедуры?

Кто нибудь сможет ответить?

Я может чего то не знаю, просто хотелось бы в процедуру передавать параметры, и делать это безопасно (я про скл-иньект), а подготовка запроса обеспечит безопасность. Если можно иначе (без всяких там магик-квотесов) расскажите, буду рад.

Неактивен

 

#23 30.10.2008 13:42:16

EugeneTM
Гуру
Зарегистрирован: 11.04.2008
Сообщений: 89

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

MaxRed написал:

EugeneTM написал:

А зачем готовить вызов хранимой процедуры?

Кто нибудь сможет ответить?

Я может чего то не знаю, просто хотелось бы в процедуру передавать параметры, и делать это безопасно (я про скл-иньект), а подготовка запроса обеспечит безопасность. Если можно иначе (без всяких там магик-квотесов) расскажите, буду рад.

В MySQLi

$param = $mysqli->real_escape_string($str); // искейпишь параметр - это всегда делать и не только по соображениям безопасности и не только с процедурами.
$result = $mysqli->query("CALL test_proc('$param')") // выполняешь процедуру. Счас не помню - могу путать в каком месте одинарные в каком двойные кавычки при этом вызове

В PDO аналог real_escape_string - quote

Процедура - это уже подготовленный запрос(ы), которому ты подпихиваешь параметры. Только функционально мощнее на порядок.

Неактивен

 

#24 30.10.2008 13:47:03

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

Для безопасной работы с MySQL достаточно одной-единственной функции - mysql_escape_string(). Пропускайте передаваемые параметры через неё, и всё будет хорошо.
Судя по приводимому коду, у Вас создание PREPARE STATEMENT лишнее, вызывайте просто процедуру:


$h_ = mysql_escape_string($h);a
$sql = "CALL data($h_)"; // а Вы, кстати, число в процедуру передаёте? Если процедура ждет строку, то будет ошибка - надо тогда писать в одинарных кавычках - CALL data('$h_')
mysql_query($sql) or die (mysql_error());
 


Кстати.  А зачем вообще бывают нужны всякие там mysqli и тому подобное? Удобнее так?
(реально интересно, т.к. сам никогда не использовал, всегда писал через mysql_query() и т.п.; хотел, вот, узнать, мошт что-то теряю :о)

Неактивен

 

#25 30.10.2008 16:27:12

EugeneTM
Гуру
Зарегистрирован: 11.04.2008
Сообщений: 89

Re: PHP+MySql+mysqli+хранимые процедуры. Странный фатал ерор. %)

LazY написал:

Кстати.  А зачем вообще бывают нужны всякие там mysqli и тому подобное? Удобнее так?
(реально интересно, т.к. сам никогда не использовал, всегда писал через mysql_query() и т.п.; хотел, вот, узнать, мошт что-то теряю :о)

В MySQLi к примеру есть multiquery.
В ХП делаешь 10 SELECT'ов - потом из результата последовательно забираешь

PDO просто удобнее, кодить в разы меньше.
Можно конечно MySQL обернуть - дык PDO и получается :-)

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson