title: Problem with binding NULL value to named placeholders with associative array in execute function in PDO
body: <p>I am trying to construct and execute a delete query when the <em>table_name</em> and the <em>conditional_clauses</em> are passed as parameters in OOP fashion. I am using PDO by wrapping it in a custom wrapper. I am using prepared statements, with named placeholders. In every case, I am passing an associative array inside <code>PDO-&gt;execute()</code> function, where the array_keys are the name of the placeholders used and the array_value are the corresponding values to be substituted. I am facing issues only in one case when I want to specify an <code>IS NULL</code> condition with <em>WHERE</em> clause.</p>
  
  <p>Basically, if I want to search for something like:</p>
  
  <pre><code>SELECT * FROM EMPLOYEES WHERE salary &gt; 10000 AND skill IS NULL
  </code></pre>
  
  <p>I am able to dynamically construct a prepared statement which looks like:</p>
  
  <pre><code>$sql = SELECT * FROM employees WHERE salary &gt; :salary AND skill IS :skill
  </code></pre>
  
  <p>And then execute the prepared SQL as:</p>
  
  <pre><code>$stmt-&gt;execute(["salary" =&gt; 10000,
                  "skill" =&gt; null])
  </code></pre>
  
  <p>This is where I am facing the issue. I am getting a fatal error here only when a value is <strong>null</strong>. And, I want to include checking for IS NULL functionality in my wrapper.</p>
  
  <p><strong>Please note -</strong> </p>
  
  <ul>
  <li><p>I want to achieve the purpose without using <em>bindValue()</em> or
  <em>bindParam()</em> functions.</p></li>
  <li><p>I have turned emulation off (as MySQL can sort all placeholders out<br>
  properly).</p></li>
  <li><p>Using <strong>?</strong> as placeholders isn't an option for me. I'll have to<br>
  re-design my entire codebase otherwise.</p></li>
  </ul>
  
  <p>Here's the code snippet for reference:</p>
  
  <pre><code>&lt;?php
  class DeleteQuery {
          protected function where(array $whereCondition, array &amp;$values): string{
          $whereClause = ' WHERE ';
          $i = 0;
          $j = 0;
  
          $hasComparators = array_key_exists("comparators", $whereCondition);
          $hasConjunctions = array_key_exists("conjunctions", $whereCondition);
  
          $comparatorCount = $hasComparators ? count($whereCondition["comparators"]) : 0;
          $conjunctionCount = $hasConjunctions ? count($whereCondition["conjunctions"]) : 0;
  
          foreach ($whereCondition["predicates"] as $predicate_key =&gt; &amp;$predicate_value) {
              $whereClause .= $predicate_key;
  
              $whereClause .= ($hasComparators and ($i &lt; $comparatorCount)) ?
              ' ' . $whereCondition["comparators"][$i++] . ' ' : ' = ';
  
              if (is_array($predicate_value)) {
                  $whereClause .= "('" . implode("', '", $predicate_value) . "')";
                  unset($whereCondition['predicates'][$predicate_key]);
              } else {
                  $whereClause .= ':' . $predicate_key;
              }
  
              $whereClause .= !($hasConjunctions and ($j &lt; $conjunctionCount)) ?
              '' : ' ' . $whereCondition["conjunctions"][$j++] . ' ';
          }
  
          $values = array_merge($values, $whereCondition['predicates']);
  
          return $whereClause;
      }
  
      public function delete($tblName, $conditions) {
          $sql = "DELETE FROM " . $tblName;
          $values = [];
  
          if (!empty($conditions) &amp;&amp; is_array($conditions)) {
              /* If the stmt has WHERE clause */
              if (array_key_exists("where", $conditions)) {
                  $sql .= $this-&gt;where($conditions['where'], $values);
              }
  
              /* If the stmt has ORDER BY clause */
              if (array_key_exists("order_by", $conditions)) {
                  $sql .= $this-&gt;order_by($conditions['order_by']);
              }
  
              /* If the stmt has LIMIT clause */
              if (array_key_exists("limit", $conditions)) {
                  $sql .= $this-&gt;limit($conditions['limit'], $values);
              }
          }
  
          echo $sql . PHP_EOL;
          print_r($values);
      }
  }
  
  $deleteConditions = [
      "where" =&gt; array(
          "predicates" =&gt; ["skill" =&gt; null],
          "comparators" =&gt; ["IS"],
      ),
  
      /* other conditional clauses */
  
  ];
  $obj = new DeleteQuery();
  $obj-&gt;delete("employees", $deleteConditions);
  
  </code></pre>