Intereting Posts
Должны ли выполняться подготовленные PHP PDO заявления? 403 Запрещено на символическую ссылку в веб-корне Функция заголовка не работает на онлайн-сервере? Отчет, подготовленный PDO для обновления, не работает должным образом Настройка PHPUnit с Zend Test как получить данные mysql с помощью ajax, когда один вход заполнен PHP, извлекающий значения массива с помощью стрелки стрелки "->" Проблема с публикацией на странице Facebook с использованием скрипта PHP как учетной записи страницы Назначение значений по умолчанию для Smarty с использованием объектно-ориентированного стиля Как определить HTTP-метод в CodeIgniter добавление запроса SUM () в mySQL JOIN Безопасно ли использовать миграции doctrine2 в производственной среде с symfony2 и php Symfony 3.4 Используйте представление внутри моего пакета Получить значение из массива PHP включает файл в динамическом URL-адресе

SQLSTATE : недопустимый номер параметра: параметр не определен (PDO)

Я знаю: это было сделано до смерти.

Но, поверьте, я довольно долго изучал, как это исправить. То, что я пытаюсь достичь, – это оболочка базы данных PDO MySQL для использования с PDO, которую я могу просто включить в свой код. Моя главная проблема связана, в частности, с двумя функциями, а также с фактической привязкой параметров, которые я пытаюсь достичь. Причина, по которой я заявляю две функции, а не одну, – несмотря на мои усилия, я не смог определить, кто пытается эту проблему. Я имею переменную var_dump ed, которая подтвердила, что это не переменная, это что-то другое. Тем не менее, тот факт, что я получаю эту ошибку на первом месте, означает, что с кодом что- то должно быть не так.

Приложение A: fetch( $table, $columns, $whereArgs )

Цель этой функции – просто получить строку. Это достигается путем принятия таблицы строки для извлечения, а также любых столбцов и предложений where-clauses для выполнения конкретной задачи. Как только параметры были отправлены, вызывается одна или две петли, которые динамически формируют запрос.

 public function fetch( $table, $columns, $whereArgs ) { if ( $whereArgs === NULL && $columns === NULL ) return false; $select = "SELECT "; $where = " WHERE "; $iQuery = 0; $sqlParams = array(); $columnCount = count( $columns ) - 1; foreach( $whereArgs as $key => $value ) { $paramKey = sprintf( ':%s', $key ); $where .= sprintf( "`%s`= %s", $key, $paramKey ); $sqlParams[ "{$paramKey}" ] = sprintf( "%s", $value ); if ( $iQuery <= $columnCount ) { $select .= sprintf( '`%s`', $columns[ $iQuery ] ); $select .= ', '; } else { $select .= ' '; } ++$iQuery; } if ( $iQuery <= $columnCount ) { for( ; $iQuery < $columnCount; ++$iQuery ) { if ( $iQuery < $columnCount ) { $select .= sprintf( '`%s`', $columns[ $iQuery ] ); $select .= ', '; } else { $select .= ' '; } } } $select .= sprintf( "FROM `%s`", $table ); $query = $select . $where; return $this->doQuery( $query, $sqlParams, TRUE, QueryType::Row ); } 

Приложение B: doQuery( $query, $sqlParams, $return = FALSE, $queryType = QueryType::None )

Эта функция относительно проста: все, что она делает, – это значения привязки и выполнение оператора, а также оперативную проверку того, какой тип возвращается (типы возврата, которые являются либо «строка», «столбец», либо «все»), определяются class QueryType , класс, который выходит за рамки этой проблемы), а затем возвращает все, что требуется.

 protected function doQuery( $query, $sqlParams, $return = FALSE, $queryType = QueryType::None ) { $statement = $this->mConnection->prepare( $query ); foreach( $sqlParams as $param => $value ) { $statement->bindValue( $param, $value ); } $statement->execute( ); if ( $return ) { switch( $queryType ) { case QueryType::Row: return $statement->fetch( ); case QueryType::Column: return $statement->fetchColumn( ); case QueryType::All: return $statement->fetchAll( ); case QueryType::None: return $statement; default: return false; } } } 

Иллюстрация C: test.php

Это просто небольшой тестовый сценарий, который я написал для проверки базы данных.

 $database = new Database( 'evolve_admin' ); $res = $database->fetch( 'evol_users', array( 'user.id', 'user.email', 'user.firstname' ), array( 'user.email' => 'test1234@test.com' ) ); var_dump( $res ); 

Другие комментарии

Я узнал, что с моим кодом что-то не так, я просто потерял то, что именно может быть. Что касается моих навыков отладки, я изучил этот вопрос совсем немного, и кажется, что эта ошибка очень распространена. Моя главная цель – заставить эту оболочку работать, и если кто-нибудь увидит какие-либо ошибки внутри самого кода (в том числе те, которые не входят в объем этой проблемы в частности), сообщите мне.

Каждому, кто предлагает руку в этом: большое спасибо.

    Я думаю, вы прогоняете некоторые места там:

     $where .= sprintf( "`%s`= %s", $key, $paramKey ); 

    В следующий раз, когда вы использовали переменную $wher вы добавили ее в $select .

    Если больше того, где arg где:

     WHERE `%s`= %s`%s`= %s`%s`= %s`%s`= %s`%s`= %s 

    Вы не сделали ошибку с мыслью о SELECT. Кстати, у вас есть две одинаковые петли и тесты для вашего поколения выбора, if ( $iQuery <= $columnCount ) . Один в петле где и снаружи. Какая польза?

    Edit: И, конечно, я забыл указать, почему у вас эта ошибка:

     $sqlParams[ "{$paramKey}" ] = sprintf( "%s", $value ); 

    Вы создаете таблицу, которая будет выглядеть так: array ( "{:akey}" => "avalue") (я считал значение как строку. Почему вы использовали фигурные скобки ({}), это полностью изменит имя ключа ( должно быть :keyname not {:keyname }

    Редактировать 2: было в хорошем настроении, поэтому здесь приведена упрощенная версия вашего метода выборки (не проверена, но должна работать нормально)

     /* * $whereArgs default value is an array, so you can call a select * without an empty array supplied if you does not have some where clause arguments * The separator is how the element will be binded alltogether in the where clause */ public function fetch( $table, $columns, $whereArgs = array(), $separator= 'AND' ) { /* We return false, if the columns variable is not set, or is not an array, * or (if it is an array) does not contain anything * or the $whereArgs is not and array (it would mean something bad have been given) */ if ( false == isset($columns) || false == is_array($columns) || 0 == count($columns) || false == is_array($whereArgs) ) { return false; } $select = "SELECT"; $from = " FROM `$table`"; $where = " WHERE "; /* SELECT generation */ for ( $columIt = 0; $columIt < count($columns); $columIt++) { $select .= " " . $columns[$columIt]; // We check if we need to add a ',' if ( $columIt+1 < count($columns) ) { $select .= ","; } } /* WHERE clause generation */ $sqlParams = array(); $whereIt = 0; foreach( $whereArgs as $key => $value ) { $stripedKey = preg_replace('/\\./', '_', $key); $where .= " $key= :$stripedKey"; $sqlParams[ ":$stripedKey" ] = "$value"; // We check if we need to add a where separator if ( $whereIt +1 < count($whereArgs ) ) { $select .= " $separator"; } $whereIt++; } /* the generated where clause is only printed if $whereArgs * is not an empty array */ $query = $select . $from . ((0<count($whereArgs))?$where:""); return $this->doQuery( $query, $sqlParams, TRUE, QueryType::Row ); } , /* * $whereArgs default value is an array, so you can call a select * without an empty array supplied if you does not have some where clause arguments * The separator is how the element will be binded alltogether in the where clause */ public function fetch( $table, $columns, $whereArgs = array(), $separator= 'AND' ) { /* We return false, if the columns variable is not set, or is not an array, * or (if it is an array) does not contain anything * or the $whereArgs is not and array (it would mean something bad have been given) */ if ( false == isset($columns) || false == is_array($columns) || 0 == count($columns) || false == is_array($whereArgs) ) { return false; } $select = "SELECT"; $from = " FROM `$table`"; $where = " WHERE "; /* SELECT generation */ for ( $columIt = 0; $columIt < count($columns); $columIt++) { $select .= " " . $columns[$columIt]; // We check if we need to add a ',' if ( $columIt+1 < count($columns) ) { $select .= ","; } } /* WHERE clause generation */ $sqlParams = array(); $whereIt = 0; foreach( $whereArgs as $key => $value ) { $stripedKey = preg_replace('/\\./', '_', $key); $where .= " $key= :$stripedKey"; $sqlParams[ ":$stripedKey" ] = "$value"; // We check if we need to add a where separator if ( $whereIt +1 < count($whereArgs ) ) { $select .= " $separator"; } $whereIt++; } /* the generated where clause is only printed if $whereArgs * is not an empty array */ $query = $select . $from . ((0<count($whereArgs))?$where:""); return $this->doQuery( $query, $sqlParams, TRUE, QueryType::Row ); } 

    Редактировать 3: BTW не видел ваш тестовый образец, но имя параметра не может содержать '.' голец

    Редактировать 4: Не видел, что вы решили, я добавил pre_replace, чтобы заменить '.' в вашем подмножестве. Также избавляйтесь от символа “ ', когда эхо ключа, запрос не сработает иначе

     `user.email`=:arg 

    Не нравится =)

     user.email=:arg or user.`email`=:arg 

    Предпочтительный (`) используется для включения специального символа в имени столбца, поэтому, как и раньше, имя столбца не соответствует ни одному существующему.

    Редактирование 5: Вместо того, чтобы удалять свой ключ, чтобы создать аргументы и массив аргументов. Вы можете безопасно использовать то, что предотвращает появление ошибочных халахов, используя опцию $ whereIt:

     $where .= " $key= :arg_$whereIt"; $sqlParams[ ":arg_$whereIt" ] = "$value"; 

    С уважением

    Проблема была связана с тем, что каждый столбец, который я имел в своем тестовом db, имел «.». между «пользователем» и именем столбца. Я решил проблему, просто заменив каждый период знаком подчеркивания и избавился от этой ошибки. Хотя запрос по-прежнему не работает по какой-то причине, я уверен, что все будет хорошо.

    Так, например:

    user.email = user_email .