title: PHP: Fatal error: Call to a member function on a non-object
body: <p>Getting a very strange error here, I am writing a flatfile database class and this was all working fine until I refreshed and now I am constantly getting this message:</p>
  
  <blockquote>
    <p><strong>Fatal error</strong>: Call to a member function name() on a non-object in
    <strong>/home/reithg/public_html/test/engine/class.database.php</strong> on line <strong>50</strong></p>
  </blockquote>
  
  <p>I am calling the Class as follows:</p>
  
  <pre><code>&lt;?php
  ini_set('display_errors', '1');
  
  require('engine/class.database.php');
  
  $config = new Config("lessons", array('first', 'second', 'third', 'fourth'), "data/");
  $db = new Database($config, true);
  
  print("Querying DB for 'theta' no exclusions: &lt;br /&gt;");
  print_r($db-&gt;query('theta', NULL, NULL));
  
  print("&lt;p /&gt; Querying DB for 'theta' in column 'second': &lt;br /&gt;");
  print_r($db-&gt;query('theta', 'second', NULL));
  
  print("&lt;p /&gt; Querying DB for first two rows: &lt;br /&gt;");
  print_r($db-&gt;getRows(2));
  
  print("&lt;p /&gt; Querying DB for last three rows: &lt;br /&gt;");
  print_r($db-&gt;getRows(3, true));
  
  print("&lt;p /&gt; Cleaning data for safe DB input: &lt;br /&gt;");
  $testInput = array('escape|these||delimiters','and\these\\slashes','and\0these\0nulls',"don't, forget quotes");
  print("input: ");
  print_r($testInput);
  echo("&lt;br /&gt;output: ");
  print($db-&gt;addRow($testInput));
  ?&gt;
  </code></pre>
  
  <p>Here is my <strong>class.database.php</strong></p>
  
  <pre><code>&lt;?php
  require('class.config.php');
  require('class.column.php');
  
      class Database {
          private
              $_config,
              $_pointer;
  
          public function __construct(Config $config)  {
              $this-&gt;_config = $config;
              return true;
          }
  
          private function connect($method) {
              if (!($this-&gt;_pointer = @fopen($this-&gt;_config-&gt;db(), $method)))
              echo("Unable to connect to database");
          }
  
          private function disconnect() {
              fclose($this-&gt;_pointer);
          }
  
          private function lock($method) {
              if(flock($this-&gt;_pointer, $method))
                  return true;
              return false;
          }
  
          private function unlock() {
              flock($this-&gt;_pointer, LOCK_UN);
          }
  
          private function cleanInput($input) {   
              $data = array_map(array($this, 'escapeData'), $input);
              $output = implode($this-&gt;_config-&gt;delimiter(), $data)."\r\n";
              return $output;
          }
  
          private function escapeData($data) 
          {
              $search = array('\\', '"', "'", '\\0', '\n', $this-&gt;_config-&gt;delimiter());
              $replace = array('\\\\', '\"', "\'", '\\0', '\\n', '\\'.$this-&gt;_config-&gt;delimiter());
              $output = str_replace(array_unique($search), array_unique($replace), $data);
              return $output;
          }
  
          private function formatRow($data) {
              foreach($data as $key =&gt; $value) {
                  $row[$this-&gt;_config-&gt;columns($key, "position")-&gt;name()] = $value;
              }
              return $row;
          }
  
          public function dumpToArray() {
              $arrayDump;
              foreach(file($this-&gt;_config-&gt;db(), FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $row =&gt; $content)
                  $arrayDump[$row] = formatRow(explode($this-&gt;_config-&gt;delimiter(),$content));
              return $arrayDump;
          }
  
          public function addRow(array $data) {
              $this-&gt;connect('ab');
              if($this-&gt;lock(LOCK_EX)) {
                  // fwrite($this-&gt;_pointer, $this-&gt;cleanInput($data));
                  echo($this-&gt;cleanInput($data));
                  $this-&gt;unlock();
                  $this-&gt;disconnect();
                  return true;
              } else {
                  $this-&gt;disconnect();
                  return false;
              }
          }
  
          public function query($value, $column = NULL, $limit = NULL) {
              $this-&gt;connect('rb');
              $results = array();
              while ((is_null($limit) || (count($results) &lt; $limit)) &amp;&amp; !feof($this-&gt;_pointer)) {
                  $data = explode($this-&gt;_config-&gt;delimiter(), fgets($this-&gt;_pointer, 1024));
                  if(!is_null($column)) {
                      if ($data[$this-&gt;_config-&gt;columns($column, "string")-&gt;index()] == $value)
                          array_push($results, $this-&gt;formatRow($data));
                  } else {
                      if (in_array($value, $data))
                          array_push($results, $this-&gt;formatRow($data));
                  }
              }
              $this-&gt;disconnect();
              switch (count($results)) {
                  case 0;
                      return false;
                  case 1;
                      return $results[0];
                  default;
                      return $results;
              }
          }
  
          public function getRows($limit = 1, $reverse = false) {
              $this-&gt;connect('rb');
              $offset = 0;
              $results = array();
              if ($reverse) {
                  while(count($results) &lt; $limit &amp;&amp; fseek($this-&gt;_pointer, $offset, SEEK_END) &gt;= 0) {
                      $char = fgetc($this-&gt;_pointer);
                      if($char == "\n" || $char == "\r"){
                          $offset --;
                          $data = explode($this-&gt;_config-&gt;delimiter(), fgets($this-&gt;_pointer, 1024));
                          array_push($results, $this-&gt;formatRow($data));
                      }
                      $offset--;
                  }
                  $results = array_reverse($results);
              } else {
                  while ((($limit === NULL) || (count($results) &lt; $limit)) &amp;&amp; !feof($this-&gt;_pointer)) {
                      $data = explode($this-&gt;_config-&gt;delimiter(), fgets($this-&gt;_pointer, 1024));
                      array_push($results, $this-&gt;formatRow($data));
                  }
              }
              $this-&gt;disconnect();
              return $results;
          }
      }
  ?&gt;
  </code></pre>
  
  <p><strong>class.config.php</strong></p>
  
  <pre><code>&lt;?php
      class Config {
          private
              $_db,
              $_file,
              $_columns = array(),
              $_directory,
              $_delimiter;
  
          public function __construct($file, array $columns, $directory = NULL, $delimiter = "|")  {
              $this-&gt;_db = $directory.$file.".db";
              $this-&gt;defineColumns($columns);
              $this-&gt;_directory = $directory;
              $this-&gt;_delimiter = $delimiter;
          } 
  
          public function db() {
              return $this-&gt;_db;
          }
  
          public function delimiter() {
              return $this-&gt;_delimiter;
          }       
  
          private function defineColumns($constants) {
              for ($i=0;$i&lt;count($constants);$i++) {
                  if(in_array($constants[$i], $this-&gt;_columns))
                      die("Column names must be unique");
                  $column = new Column($constants[$i], $i);
                  $this-&gt;_columns[$column-&gt;name()] = $column;
              }
          }
  
          public function columns($index, $search = "string") {
              switch ($search) {
                  case "string";
                      return $this-&gt;_columns[$index];
                      break;
                  case "position";
                      $keys = array_keys($this-&gt;_columns);
                      return $this-&gt;_columns[$keys[$index]];
                      break;
                  default;
                      return false;
              }   
          }
      }
  ?&gt;
  </code></pre>
  
  <p><strong>class.column.php</strong></p>
  
  <pre><code>&lt;?php
      class Column { 
          const
              ALL = "0",
              STRING = "1",
              NUMBER = "2",
              INT = "3",
              AUTO_INCREMENT = "4",
              CURRENT_TIME = "5";
  
          private
              $_type = ALL,
              $_name,
              $_index,
              $_maxChars = "256";
  
          public function __construct($name, $index, $type = NULL, $maxChars = NULL)  {
              $this-&gt;_name = $name;
              $this-&gt;_index = $index;
              if(!is_null($type))
                  setDataType($type);
              if(!is_null($maxChars))
                  setMaxChars($maxChars);
              return $this;
          }
  
          public function setDataType($type) {
              switch ($type) {
                  case ALL;
                  case STRING;
                  case NUMBER;
                  case INT;
                  case AUTO_INCREMENT;
                  case CURRENT_TIME;
                      $this-&gt;_type = $type;
                      break;
                  default;
                      return false;
              }
          }
  
          public function auditData($data) {
              switch ($this-&gt;_type) {
                  case ALL;
                      $output = $data;
                      break;
                  case STRING;
                      $output = (string) $data;
                      break;
                  case NUMBER;
                      $output = (float) $data;
                      break;
                  case INT;
                      $output = (int) $data;
                      break;
                  case AUTO_INCREMENT;
                      $output = (int) $data;
                      break;
                  case CURRENT_TIME;
                      $output = time();
                      break;
                  default;
                      return false;
              }
              return $output;
          }
  
          public function setMaxChars($maxChars) {
              if(is_int($maxChars)) {
                  $this-&gt;_maxChars = $maxChars;
              }
          }
  
          public function name() {
              return $this-&gt;_name;
          }
  
          public function index() {
              return $this-&gt;_index;
          }
      }
  ?&gt;
  </code></pre>
  
  <p>I know it's a lot of code but I can't work out why this is happening all of a sudden, literally in one refresh without any change to code. Even if I backtrace to earlier versions that also worked this is happening.</p>
  
  <p>When I attempt to do:</p>
  
  <pre><code>print($this-&gt;_config-&gt;columns($key, "position"));
  </code></pre>
  
  <p>It returns:</p>
  
  <blockquote>
    <p><strong>Catchable fatal error:</strong> Object of class Column could not be converted
    to string in <strong>/home/reithg/public_html/test/engine/class.database.php</strong>
    *<em>on line 50</em>*</p>
  </blockquote>
  
  <p>Which shows that I am performing <code>name()</code> on a member of class Column which has a public method called <code>name()</code></p>
  
  <p>When I do:</p>
  
  <pre><code>print($this-&gt;_config-&gt;columns($key, "position")-&gt;name());
  </code></pre>
  
  <p>it returns (one word per time as it is in a foreach loop);</p>
  
  <blockquote>
    <p>first second third fourth first second third fourth</p>
  </blockquote>
  
  <p>So it is clearly working 1 line before it.</p>