title: How to insert null to Postgres from PHP
body: <p>I have been working on a project management system and I'm coding it with PHP and PostgreSQL 8.4 and Model-View-Controller.</p>
  <p>To put you people in context I will explain from the root (as short as I can).</p>
  <p>I have a class called <code>Actividad</code> that extends a database abstraction class to execute the queries.</p>
  <pre><code>    class Actividad extends AbstraccionBD
      {      
      
      /**
       * Constructor de la clase
       *
       * @param String  $nom  Nombre 
       * @param String  $des  Descripción
       * @param String  $fi   Fecha de inicio
       * @param String  $fc   Fecha de culminación
       * @param Float   $pon  Ponderación
       * @param Boolean $crit Crítica
       * @param String  $le   Lugar Ejeucución
       * @param String  $rec  Recursos
       * @param Integer $pe   Presupuesto estimado
       * @param String  $est  Estado
       * @param Integer $cal  Calificación
       * @param Integer $peje Presupuesto ejecutado
       * @param Integer $asis Asistencia
       */
      public function __construct($nom, $des, $fi, $fc, $pon, $crit, $le, $rec, 
                                  $pe, $est, $cal, $peje, $asis)
      {
  
          //Asignamos todos los valores especificados al 
          //objeto
          $this-&gt;nombre = $nom;
          $this-&gt;descripcion = $des;
          $this-&gt;fecha_inicio = $fi;
          $this-&gt;fecha_culminacion = $fc;
          $this-&gt;ponderación = $pon;
          $this-&gt;es_critica = $crit;
          $this-&gt;lugar_ejecucion = $le;
          $this-&gt;recursos = $rec;
          $this-&gt;presupuesto_est = $pe;
          $this-&gt;estado = $est;
          $this-&gt;calificacion = $cal;
          $this-&gt;presupuesto_ejec = $peje;
          $this-&gt;asistencia = $asis;
          
      }
  
      public function insertarObjeto()
      {
          //Construimos el query de inserción de datos en la tabla
          //actividad; nótese que se llama al procedimiento almacenado
          //sga.max_num_actividad(int,int) para determinar el número
          //de la actividad que se esta insertando.
          $this-&gt;_query = 
              &quot;INSERT INTO sga.actividades &quot; . 
                  &quot;(proyecto, ejec_proyecto, num_actividad, nombre, &quot; . 
                  &quot;descripcion, fecha_inicio, fecha_culminacion, &quot; .
                  &quot;ponderacion, critica, lugar_ejecucion, recursos, &quot; . 
                  &quot;prepuesto_estimado, estado, calificacion, &quot; . 
                  &quot;presupuesto_ejecutado, asistencia) &quot; . 
              &quot;VALUES &quot; . 
                  &quot;($this-&gt;proyecto, $this-&gt;ejec_proyecto, &quot; . 
                  &quot;sga.max_num_act($this-&gt;proyecto, $this-&gt;ejec_proyecto) + 1, &quot; . 
                  &quot;'$this-&gt;nombre', &quot; . 
                  &quot;'$this-&gt;descripcion', '$this-&gt;fecha_inicio', &quot; . 
                  &quot;'$this-&gt;fecha_culminacion', $this-&gt;ponderación, &quot; . 
                  &quot;$this-&gt;es_critica, '$this-&gt;lugar_ejecucion', &quot; . 
                  &quot;'$this-&gt;recursos', $this-&gt;presupuesto_est, &quot; . 
                  &quot;'$this-&gt;estado', $this-&gt;calificacion, &quot; . 
                  &quot;$this-&gt;presupuesto_ejec, $this-&gt;asistencia);&quot;;
                  
          //Ejecutamos el query de inserción
          $this-&gt;ejecutarQuery();
      }
  </code></pre>
  <p>(I was asked to keep it 80 chars per line for the project.)</p>
  <p><strong>Table definition</strong> (no FK taken in consideration):</p>
  <pre><code>CREATE TABLE sga.actividades
  (
      proyecto integer NOT NULL,
      ejec_proyecto integer NOT NULL,
      num_actividad smallint NOT NULL,
      nombre character varying(150),
      descripcion character varying(500),
      fecha_inicio date NOT NULL,
      fecha_culminacion date NOT NULL,
      ponderacion numeric (3,2) NOT NULL DEFAULT 0.00,
      critica boolean NOT NULL DEFAULT FALSE,
      lugar_ejecucion character varying(100),
      recursos character varying(250),
      prepuesto_estimado integer,
      estado sga.estados_actividad NOT NULL, -- Dominio estados_actividad
      calificacion integer,
      presupuesto_ejecutado integer,
      asistencia smallint, 
      CONSTRAINT actividad_pkey
          PRIMARY KEY(proyecto, ejec_proyecto, num_actividad)
  );
  </code></pre>
  <p>Now, what I'm trying to do is to pass the values from the model, 'something' like this:</p>
  <pre><code>    $a = new Actividad('Actividad1','DescA1', '14-07-14','14-07-14',0.00, 
                  'false',null,null,0,'ACT',null, null, null);
  
      //Dont worry im using __set method
      $act-&gt;proyecto = 1;
      $act-&gt;ejec_proyecto = 1;
  
      $a-&gt;insertarObjeto();        
  </code></pre>
  <p>As you can see I'm passing some <code>NULL</code> values in the constructor because in the DB those values can be null, all cool so far.</p>
  <p>When I try to run it I get this query:</p>
  <pre><code>INSERT INTO sga.actividades 
      (proyecto, ejec_proyecto, 
      num_actividad, nombre, 
      descripcion, fecha_inicio, 
      fecha_culminacion,
      ponderacion, critica, 
      lugar_ejecucion, recursos, 
      prepuesto_estimado, estado, 
      calificacion, presupuesto_ejecutado, 
      asistencia) 
  VALUES 
      (1, 1, sga.max_num_act(1, 1) + 1, 
      'Actividad1', 'DescA1', '14-07-14', 
      '14-07-14', 0, false, '', '', 0, 'ACT', , , );
  </code></pre>
  <p>Here's my problem: this query will never run because I'm using <code>NULL</code> keyword from PHP and when it's converted into a string in the 'concatenation madness', it stays empty (nothing in the string), so Postgres (as expected) sends the syntax error in the <code>(, , ,)</code> part.</p>
  <p>I need to replace those empty strings (<code>''</code>) with the <code>NULL</code> keyword so that Postgres recognizes and inserts it correctly.</p>
  <p>Also, some of the values passed in the constructor are wrapped into single quotes in the <code>insertarObjeto()</code> function (they are <code>character varying</code> in the DB).</p>
  <p>And in Postgres <code>''</code> is not the same as <code>NULL</code>.</p>
  <h3>What I tried to fix this</h3>
  <p>One way is to put (N) if-else statements and concatenate the correct on each case (which is kind of ugly for future maintenance of the code and system expansions), something like this:</p>
  <pre><code>if(is_null($this-&gt;asistencia))
  {
      $this-&gt;_query .= &quot;null, &quot;;
  }
  else
  {
      $this-&gt;_query .= &quot;$this-&gt;asistencia, &quot;;
  }
  </code></pre>
  <p>The problem in that approach is that there are to many attributes (and I have classes with far more that this one).</p>
  <p>Another way I saw is to wrap null in single quotes in the constructor. That works for integer (bad solution I know), but those wrapped in single quotes already in the function will throw 'null' in the query, which is also wrong, i.e:</p>
  <pre><code>INSERT INTO sga.actividades 
          (proyecto, ejec_proyecto, 
          num_actividad, nombre, 
          descripcion, fecha_inicio, 
          fecha_culminacion,
          ponderacion, critica, 
          lugar_ejecucion, recursos, 
          prepuesto_estimado, estado, 
          calificacion, presupuesto_ejecutado, 
          asistencia) 
      VALUES 
          (1, 1, sga.max_num_act(1, 1) + 1, 
          'Actividad1', 'DescA1', '14-07-14', 
          '14-07-14', 0, false, 'null', 'null', 0, 'ACT', null ,null ,null );
  </code></pre>
  <p>Is there a better solution for this? Other than (n) if-else statements?</p>