Подготовка PDO и выполнение запроса всегда возвращают ошибку

У меня есть функция,

который возвращает мне всегда ошибку, даже если в phpmyadmin, когда я прохожу запрос, есть результат.

Я предполагаю, что в моем запросе что-то не так, но я не знаю, что. Раньше я выполнял свой код, выполняя mysql_real_escape_string, затем я обращался к PDO, они сказали мне, что я должен подготовиться к экранированию переменных GET, поэтому я попытался сделать это.

Ниже мой запрос

public static function getDetailService($param) {
    global $bdd;
    $detail = $bdd->prepare('SELECT
            spb_services.spb_services__name,
            spb_services.spb_services__description,
            spb_services.spb_services__banner,
            spb_services.spb_services__tabs,
            spb_services.spb_services__category
        FROM spb_services
        WHERE spb_services.spb_services__name LIKE :service');

    $detail->bindValue(':service', $_GET[$param], PDO::PARAM_STR);
    $resultat = $detail->fetchAll(PDO::FETCH_ASSOC);

    //var_dump($_GET[$param]);

    $detail->debugDumpParams();
    $lignes = $detail->fetchColumn();

    //var_dump($lignes);
    $detail = $detail->fetchAll(PDO::FETCH_ASSOC);
    $retour = ($lignes > 0) ? array('status' => 'ok') : array('status' => 'error');
    var_dump($retour);
}

Когда я вызываю функцию: $service = nosServices::getDetailService('service');

Вар дамп var_dump($_GET[$param]) вернет мне то, что ожидалось (из URL-адреса)

Затем я сделал $detail->debugDumpParams();

Я пропустил запрос в моем локальном хосте phpmyadmin, он возвращает мне то, что ожидалось, но не при использовании PDO.

Я думаю, мелкие вещи не так, но я понятия не имею, что.

Это не возвращает ошибок, но всегда ошибка, как будто нет num_rows_result

Подводя итог, GEt возвращает то, что ожидалось, но когда мы переходим к запросу, он не возвращает никакого результата (за исключением моей копии phpmyadmin и вставки запроса)

Любая помощь будет высоко оценена

Изменить: изменения, сделанные другими пользователями, как и ожидалось.


person Stanislas Piotrowski    schedule 04.05.2016    source источник
comment
":service" уберите здесь двойные кавычки. В bindValue добавьте : перед service   -  person Daan    schedule 04.05.2016
comment
у меня еще ошибка   -  person Stanislas Piotrowski    schedule 04.05.2016
comment
это все еще не работает : SQL: [270] ВЫБЕРИТЕ spb_services.spb_services__name, spb_services.spb_services__description, spb_services.spb_services__banner, spb_services.spb_services__tabs, spb_services.spb_services__category FROM spb_services, ГДЕ spb_services.spb_services__name: LIKE 1:service :service paramno=-1 name=[8] :service is_param=1 param_type=2   -  person Stanislas Piotrowski    schedule 04.05.2016
comment
что возвращает $detail-›debugDumpParams(); ?   -  person Parth Chavda    schedule 04.05.2016
comment
SQL: [270] ВЫБЕРИТЕ spb_services.spb_services__name, spb_services.spb_services__description, spb_services.spb_services__banner, spb_services.spb_services__tabs, spb_services.spb_services__category FROM spb_services, ГДЕ spb_services.spb_services__name LIKE :service Params: 8 Ключ: Имя: имя=[8] :service is_param=1 param_type=2   -  person Stanislas Piotrowski    schedule 04.05.2016
comment
вам не хватает $detail->execute(). вам нужно выполнить запрос перед fetchAll   -  person undefined_variable    schedule 04.05.2016
comment
у людей неправильное представление о двоеточии в биндах, оно требуется только в значениях. Прочтите сами stackoverflow.com/q/9778887   -  person Funk Forty Niner    schedule 04.05.2016
comment
@StanislasPiotrowski Здесь нужно проверить наличие ошибок. Поэтому используйте php.net/manual/en/function.error-reporting.php и php.net/manual/en/pdo.error-handling. php, чтобы увидеть, получится ли что-нибудь из этого, кроме того, что вы не выполняете запрос.   -  person Funk Forty Niner    schedule 04.05.2016
comment
@StanislasPiotrowski как будто нет num_rows_result - Что именно вы имеете в виду? Если это часть кода, которую вы не показываете, и если это функция mysqli_, то нам нужно об этом знать. Если это функция mysqli_, эти разные API не смешиваются друг с другом. Вы подключаетесь к PDO, верно?   -  person Funk Forty Niner    schedule 04.05.2016
comment
да, я использую только pdo   -  person Stanislas Piotrowski    schedule 04.05.2016


Ответы (4)


В вашем коде происходит несколько странных вещей.

Я прокомментировал, где, по моему мнению, нужно что-то изменить

public static function getDetailService($param) {
    global $bdd;    // bad practice, see later suggestion
    $detail = $bdd->prepare('SELECT
                     spb_services.spb_services__name,
                     spb_services.spb_services__description,
                     spb_services.spb_services__banner,
                     spb_services.spb_services__tabs,
                     spb_services.spb_services__category
                FROM spb_services
                WHERE spb_services.spb_services__name LIKE :service');

    // $GET? I assume you want to use the `$param you pass as a param to this function
    //$detail->bindValue(':service', $_GET[$param], PDO::PARAM_STR);

    // a LIKE normally requires a string like '%something%'
    // or 'something%'
    // DO we assume you passed $param with the wildcards already applied?
    $detail->bindValue(':service', $param, PDO::PARAM_STR);

    // now the prepared query must be executed
    $detail->execute();

    // fetchAll returns ALL the result set into an array
    $resultat = $detail->fetchAll(PDO::FETCH_ASSOC);

    // as you are using a LIKE we have to assume there will be more 
    // than one row returned. 

    // fetchColumn makes no sense here
    //$lignes = $detail->fetchColumn();

    // You already did a fetchAll so this makes no sence
    //$detail = $detail->fetchAll(PDO::FETCH_ASSOC);

    // as all you appear to be doing is testing if one or more rows are returned
    // then all you need to do is coumt the occurances in the $resultat array

    $retour = (count($resultat) > 0) ? array('status' => 'ok') : array('status' => 'error');

    // Now you need to return something
    return $retour;

}

Также плохой практикой является использование global в методе класса, так как это нарушает инкапсуляцию, лучше передать что-то подобное в качестве параметра.

например это

public static function getDetailService($param) {
    global $bdd;

Становится этим

public static function getDetailService($bdd, $param) {
    // global $bdd;   <-- no longer needed

Или, если это необходимо для всего класса, сделайте его свойством класса!

Если я прав, и все, что вы хотите узнать из этого метода, это если что-то существует, SELECT COUNT(id) as cnt будет более эффективным способом сделать это, но давайте оставим это на другой день, так как это также изменит способ получения результата и напишите остальная часть этого кода

Последнее замечание: вы не выполняете проверку ошибок после того, как любой из операторов PDO может пойти не так. Почти все эти операторы PDO возвращают состояние, при котором, если оно ложно, вы должны отобразить сообщение об ошибке, сгенерированное PDO. См. Информация об ошибке

person RiggsFolly    schedule 04.05.2016
comment
вы действительно полезны, спасибо за все советы и спасибо всем за то, что взяли меня на подсказку, чтобы ответить мне. Мне пришлось бы проверить все ответы как удовлетворительные, но этот был наиболее полным и решил проблему. - person Stanislas Piotrowski; 04.05.2016

Необходимо исправить привязку параметров.

Вы пропустили : при вводе значения параметра.

Исправленный код:

...
WHERE spb_services.spb_services__name LIKE  :service');
        $detail->bindValue(':service', $_GET[$param], PDO::PARAM_STR);
...
person Pupil    schedule 04.05.2016
comment
Спасибо за вашу помощь, я сделал это, но у меня все еще нет результатов - person Stanislas Piotrowski; 04.05.2016
comment
Ну, во-первых, ОП должен удалить некоторые кавычки. - person Jay Blanchard; 04.05.2016
comment
Я сделал это, чтобы удалить цитату - person Stanislas Piotrowski; 04.05.2016
comment
Двоеточие не проблема, драйвер автоматически добавляет это. stackoverflow.com/questions/9778887/ (перейдите по ссылке на исходный код). Заполнители не цитируются. - person chris85; 04.05.2016

Единственная проблема в вашем коде. Забудьте выполнить запрос перед получением данных. Это было бы

 $detail->bindValue(':service', $_GET[$param], PDO::PARAM_STR);
 $detail->execute();// execute it first
 $resultat = $detail->fetchAll(PDO::FETCH_ASSOC);
 print_r($resultat);
person Saty    schedule 04.05.2016
comment
Я сделал все модификации, но они все равно не работают, я думаю, что я ошибаюсь где-то еще - person Stanislas Piotrowski; 04.05.2016
comment
Я сделал $detail->bindValue(':service', $_GET[$param], PDO::PARAM_STR); $detail->execute(); // execute it first $lignes = $detail->fetchColumn(); $resultat = $detail->fetchAll(PDO::FETCH_ASSOC); //var_dump($_GET[$param]); // $detail->debugDumpParams(); //var_dump($lignes); $retour = ($lignes > 0) ? array('status' => 'ok') : array('status' => 'error'); var_dump($retour); И у меня ошибка - person Stanislas Piotrowski; 04.05.2016
comment
двоеточие не требуется в привязке, только значения, здесь stackoverflow.com/q/9778887 - person Funk Forty Niner; 04.05.2016
comment
@StanislasPiotrowski по-прежнему не выполняет запрос перед получением данных - person Saty; 04.05.2016
comment
Я попробовал это `$detail-›bindValue('service', $_GET[$param], PDO::PARAM_STR); $detail-›выполнить(); // сначала выполняем $lignes = $detail-›fetchColumn(); $resultat = $detail-›fetchAll(PDO::FETCH_ASSOC);` но у меня все еще есть ошибка - person Stanislas Piotrowski; 04.05.2016
comment
никаких ошибок не отображается, только нет результата, но когда я вставляю запрос в php мой админ, он работает - person Stanislas Piotrowski; 04.05.2016
comment
это похоже на то, что значение привязки не применяется к запросу - person Stanislas Piotrowski; 04.05.2016
comment
Попробуйте с $keyword = "%".$_GET[$param]."%"; $detail->bindValue(':service', $keyword , PDO::PARAM_STR); - person Saty; 04.05.2016
comment
И, пожалуйста, проверьте, что $_GET[$param] имеет значение!! - person Saty; 04.05.2016
comment
возвращаемая строка параметра var_dump 'снос' (длина = 10) Я вставляю ваш код, он все еще не работает. Когда я вручную заменяю значение параметра get на запрос, который я вставляю в phpmyadmin, он работает. Есть что-то, что мне не хватает? - person Stanislas Piotrowski; 04.05.2016
comment
Единственная проблема в вашем коде Я думаю, вы пропустили кое-что, старина - person RiggsFolly; 04.05.2016
comment
что это за старик? - person Stanislas Piotrowski; 04.05.2016
comment
проверьте обновленные четыре строки, используйте их в своем коде и опубликуйте значение print_r($resultat);, если вы его получите! - person Saty; 04.05.2016
comment
У меня есть массив (размер = 0) пустой - person Stanislas Piotrowski; 04.05.2016
comment
Также следуйте инструкциям RiggerFolly's ответа!! - person Saty; 04.05.2016

Вы забыли сделать $detail->execute(); Для обработки SQL-запроса

$detail->bindValue(':service', $_GET[$param], PDO::PARAM_STR);
if( ! $detail->execute()) {
   die('Invalid Mysql Query!');
}
$resultat = $detail->fetchAll(PDO::FETCH_ASSOC);

Надеюсь, это поможет :)

person Yair.R    schedule 04.05.2016
comment
Немного опоздал на вечеринку, приятель - person RiggsFolly; 04.05.2016