КАК ЗАПИСАТЬ ПАРАМЕТР PHP PDO BIND

Я сейчас создаю свой собственный конструктор запросов, и я застрял с подготовленным оператором PDO. Разве невозможно зациклить BindParam PDO. Я сделал это с помощью foreach (), но он не работает, он работает только с последними данными, выполненными циклом.

$sql = "SELECT * FROM users WHERE id = :a OR fname = :b";

$array = array(":a"=>"10002345", "Josh");
$stmt = $conn->prepare($sql); 

foreach($array as $key => $value ) {
    $stmt->bindParam($key, $value);
}

$stmt->execute();

он связывает только последние данные, выполненные циклом.

Также укажите все ключи в массиве: b отсутствует

Bhavin Solanki 12.09.2018 08:45
"он работает только с последними данными, которые выполнялись в цикле" - Поясните, пожалуйста, что это значит.
deceze 12.09.2018 08:54

то, что я имею в виду, не связывает должным образом

Eeshiro Deku 12.09.2018 08:55

Я думаю, вы переопределите параметры привязки, вам также нужно выполнить $ stmt-> выполнить (); в цикле for.

Ace of Spade 12.09.2018 08:57

так что мне нужно поместить execute () внутри цикла?

Eeshiro Deku 12.09.2018 09:08

Просто попробуйте.

Ace of Spade 12.09.2018 10:28
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
6
1 603
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Лучше использовать в запросе заполнители ? и передавать в execute массив данных:

$sql = "SELECT * FROM users WHERE id = ? OR fname = ?";
$array = array("10002345", "Josh"); // you don't even need keys here
$stmt = $conn->prepare($sql); 
$stmt->execute($array);

Почему «лучше» использовать ?? Вы можете передавать в execute() даже именованные параметры.

GrumpyCrouton 14.09.2018 19:39

Только что наткнулся на это, но на всякий случай ...

Во-первых, я буду работать в предположении, что ваш пример должен был читать $array = array(":a"=>"10002345", ":b"=>"Josh");, так как проблема будет, даже если ваш ключ :b отсутствует.


В этом бите:

foreach($array as $key => $value ) {
    $stmt->bindParam($key, $value);
}

У вас нет "передано по ссылке". $value следует изменить на &$value.

foreach($array as $key => &$value ) {
    $stmt->bindParam($key, $value);
}

Это связано с тем, что подпись метода bindParam требует, чтобы значение было ссылкой на переменную:

public function bindParam ($parameter, &$variable, $data_type = PDO::PARAM_STR, $length = null, $driver_options = null) {}

(обратите внимание на & до $variable).


Конечным результатом вашего исходного запроса (без &) является то, что для всех :params будет установлено значение, которое находится в последней итерации $value в вашем исходном цикле.

Итак, результат

$sql = "SELECT * FROM users WHERE id = :a OR fname = :b";

$array = array(":a"=>"10002345", ":b"=>"Josh");

$stmt = $conn->prepare($sql); 

foreach($array as $key => $value ) {
    $stmt->bindParam($key, $value);
}

$stmt->execute();

Был бы SELECT * FROM users WHERE id = 'Josh' OR fname = 'Josh'


Использование именованных параметров (:param) имеет преимущества перед позиционными параметрами (?), поэтому стоит зарезервировать эту опцию для подготовленных операторов, в отличие от принятого ответа «лучше использовать заполнители ?», что не так.

Должен быть приемлемый ответ, но будьте осторожны с количеством именованных параметров. Использование динамического цикла не очень хорошо работает со статическим числом именованных параметров. Я имею в виду, что иногда массив параметров / значений может насчитывать больше или меньше значений, чем указанные параметры в запросе ..

mik3fly-4steri5k 13.12.2019 22:18

На уровне абстракции базы данных я использую следующие служебные функции:

/**
 * getFieldList return the list with or without PK column
 * @param bool $withID - true when including parameter
 */
static protected function getFieldList( $withID = false )
{
    if ( $withID )
        $result = '`' . static::getTableName( ) . '`' .
            '.`' . static::getPrimaryKeyName( ) . '`, ';
    else
        $result = '';

    return $result .= '`' . static::getTableName( ) . '`.' . 
        '`' . implode( '`, `'.static::getTableName( ) . '`.`', static::getFieldNames( ) ) . '`';
}

/**
 * getFieldPlaceholders - 
 * @return string - all PDO place holders prefixed :
 */
static protected function getFieldPlacholders( )
{
    return ':' . implode( ',:', static::getFieldNames( ) );
}

/**
 * getUpdateList - SQL updates section
 * @return string
 */
static private function getUpdateList( )
{
    $result = array( );
    foreach( static::getFieldNames( ) as $field ) {
        if ( $field === static::getPrimaryKeyName() ) continue;
        $result[] = '`' . $field . '`=:' . $field;
    }
    return implode( ',', $result );
}

/**
 * Bind the fields to PDO placeholdes
 * @param PDOStatement $stmt statement that the fields are bound to
 * @return void
 */
protected function bindFields( $stmt )
{
    foreach( array_keys($this->fields) as $field ) {
        if ( $field === static::getPrimaryKeyName() ) continue;
        $stmt->bindParam( ':' . $field, $this->fields[$field] );

        // echo $field . '->' . $this->fields[$field] . '<br>';
    }
}
/**
 * Bind the fields to the placeholders
 * @param PDOStatement $stmt - that the fields are bind to
 * @return void
 */
protected function bindColumns( $stmt, $withID = false )
{
    if ( $withID )
        $stmt->bindColumn( static::getPrimaryKeyName(), $this->ID );
    foreach( static::getFieldNames() as $fieldname )
    {
        $stmt->bindColumn( $fieldname, $this->fields[$fieldname] );
    }   
}

/**
 * parseResultset
 * Set the values of the select results, resets dirty (object is in sync)
 * @param mixed[] $result - associative array
 */
protected function parseResultset( $result )
{
    foreach( $result as $field=> $value ) {
        if ( $field === static::getPrimaryKeyName() )
            $this->ID = $value;
        $this->fields[$field] = $value;
    }
    $this->dirty = array();
}

Другие вопросы по теме