2011-12-15 13 views
5

Ottenere un errore molto strano qui, sto scrivendo una classe di database flatfile e tutto funzionava bene fino a quando non mi sono aggiornato e ora ricevo costantemente questo messaggio:PHP: errore irreversibile: chiamata a una funzione membro su un oggetto non

Fatal error: Call to a member function name() on a non-object in /home/reithg/public_html/test/engine/class.database.php on line 50

sto chiamando la classe come segue:

<?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: <br />"); 
print_r($db->query('theta', NULL, NULL)); 

print("<p /> Querying DB for 'theta' in column 'second': <br />"); 
print_r($db->query('theta', 'second', NULL)); 

print("<p /> Querying DB for first two rows: <br />"); 
print_r($db->getRows(2)); 

print("<p /> Querying DB for last three rows: <br />"); 
print_r($db->getRows(3, true)); 

print("<p /> Cleaning data for safe DB input: <br />"); 
$testInput = array('escape|these||delimiters','and\these\\slashes','and\0these\0nulls',"don't, forget quotes"); 
print("input: "); 
print_r($testInput); 
echo("<br />output: "); 
print($db->addRow($testInput)); 
?> 

Ecco il mio class.database.php

<?php 
require('class.config.php'); 
require('class.column.php'); 

    class Database { 
     private 
      $_config, 
      $_pointer; 

     public function __construct(Config $config) { 
      $this->_config = $config; 
      return true; 
     } 

     private function connect($method) { 
      if (!($this->_pointer = @fopen($this->_config->db(), $method))) 
      echo("Unable to connect to database"); 
     } 

     private function disconnect() { 
      fclose($this->_pointer); 
     } 

     private function lock($method) { 
      if(flock($this->_pointer, $method)) 
       return true; 
      return false; 
     } 

     private function unlock() { 
      flock($this->_pointer, LOCK_UN); 
     } 

     private function cleanInput($input) { 
      $data = array_map(array($this, 'escapeData'), $input); 
      $output = implode($this->_config->delimiter(), $data)."\r\n"; 
      return $output; 
     } 

     private function escapeData($data) 
     { 
      $search = array('\\', '"', "'", '\\0', '\n', $this->_config->delimiter()); 
      $replace = array('\\\\', '\"', "\'", '\\0', '\\n', '\\'.$this->_config->delimiter()); 
      $output = str_replace(array_unique($search), array_unique($replace), $data); 
      return $output; 
     } 

     private function formatRow($data) { 
      foreach($data as $key => $value) { 
       $row[$this->_config->columns($key, "position")->name()] = $value; 
      } 
      return $row; 
     } 

     public function dumpToArray() { 
      $arrayDump; 
      foreach(file($this->_config->db(), FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $row => $content) 
       $arrayDump[$row] = formatRow(explode($this->_config->delimiter(),$content)); 
      return $arrayDump; 
     } 

     public function addRow(array $data) { 
      $this->connect('ab'); 
      if($this->lock(LOCK_EX)) { 
       // fwrite($this->_pointer, $this->cleanInput($data)); 
       echo($this->cleanInput($data)); 
       $this->unlock(); 
       $this->disconnect(); 
       return true; 
      } else { 
       $this->disconnect(); 
       return false; 
      } 
     } 

     public function query($value, $column = NULL, $limit = NULL) { 
      $this->connect('rb'); 
      $results = array(); 
      while ((is_null($limit) || (count($results) < $limit)) && !feof($this->_pointer)) { 
       $data = explode($this->_config->delimiter(), fgets($this->_pointer, 1024)); 
       if(!is_null($column)) { 
        if ($data[$this->_config->columns($column, "string")->index()] == $value) 
         array_push($results, $this->formatRow($data)); 
       } else { 
        if (in_array($value, $data)) 
         array_push($results, $this->formatRow($data)); 
       } 
      } 
      $this->disconnect(); 
      switch (count($results)) { 
       case 0; 
        return false; 
       case 1; 
        return $results[0]; 
       default; 
        return $results; 
      } 
     } 

     public function getRows($limit = 1, $reverse = false) { 
      $this->connect('rb'); 
      $offset = 0; 
      $results = array(); 
      if ($reverse) { 
       while(count($results) < $limit && fseek($this->_pointer, $offset, SEEK_END) >= 0) { 
        $char = fgetc($this->_pointer); 
        if($char == "\n" || $char == "\r"){ 
         $offset --; 
         $data = explode($this->_config->delimiter(), fgets($this->_pointer, 1024)); 
         array_push($results, $this->formatRow($data)); 
        } 
        $offset--; 
       } 
       $results = array_reverse($results); 
      } else { 
       while ((($limit === NULL) || (count($results) < $limit)) && !feof($this->_pointer)) { 
        $data = explode($this->_config->delimiter(), fgets($this->_pointer, 1024)); 
        array_push($results, $this->formatRow($data)); 
       } 
      } 
      $this->disconnect(); 
      return $results; 
     } 
    } 
?> 

class.config.php

<?php 
    class Config { 
     private 
      $_db, 
      $_file, 
      $_columns = array(), 
      $_directory, 
      $_delimiter; 

     public function __construct($file, array $columns, $directory = NULL, $delimiter = "|") { 
      $this->_db = $directory.$file.".db"; 
      $this->defineColumns($columns); 
      $this->_directory = $directory; 
      $this->_delimiter = $delimiter; 
     } 

     public function db() { 
      return $this->_db; 
     } 

     public function delimiter() { 
      return $this->_delimiter; 
     }  

     private function defineColumns($constants) { 
      for ($i=0;$i<count($constants);$i++) { 
       if(in_array($constants[$i], $this->_columns)) 
        die("Column names must be unique"); 
       $column = new Column($constants[$i], $i); 
       $this->_columns[$column->name()] = $column; 
      } 
     } 

     public function columns($index, $search = "string") { 
      switch ($search) { 
       case "string"; 
        return $this->_columns[$index]; 
        break; 
       case "position"; 
        $keys = array_keys($this->_columns); 
        return $this->_columns[$keys[$index]]; 
        break; 
       default; 
        return false; 
      } 
     } 
    } 
?> 

class.column.php

<?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->_name = $name; 
      $this->_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->_type = $type; 
        break; 
       default; 
        return false; 
      } 
     } 

     public function auditData($data) { 
      switch ($this->_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->_maxChars = $maxChars; 
      } 
     } 

     public function name() { 
      return $this->_name; 
     } 

     public function index() { 
      return $this->_index; 
     } 
    } 
?> 

So che è un sacco di codice, ma non riesco a capire perché questo sta accadendo tutto all'improvviso, letteralmente in un aggiornamento senza alcuna modifica al codice. Anche se torno indietro alle versioni precedenti che ha funzionato anche questo sta accadendo.

Quando tento di fare:

print($this->_config->columns($key, "position")); 

Restituisce:

Catchable fatal error: Object of class Column could not be converted to string in /home/reithg/public_html/test/engine/class.database.php *on line 50*

che dimostra che sto eseguendo name() su un membro della Colonna classe che ha un metodo pubblico chiamato name()

Quando lo faccio:

print($this->_config->columns($key, "position")->name()); 

restituisce (una parola per volta come in un ciclo foreach);

first second third fourth first second third fourth

Quindi è chiaramente funzionante 1 riga prima.

+5

Debug: ciò che ognuno di noi fa fino al 90% del giorno. Quindi dovresti – zerkms

+0

Difficile dirlo, amico. Dovresti prestare attenzione alla linea dell'errore e trovare quale oggetto di $ this this -> _ config-> columns ($ key, "position") -> name() 'non funziona. –

+0

@ Márcio Ho notato questo, ma '$ this -> _ config-> columns ($ key," position ")' sta restituendo un membro della classe 'Column' che ha un metodo' name() '. @zerkms Questo è un errore improvviso ed è dovuto a nessun cambiamento che ho ovviamente cercato di eseguire il debug ma quando ciò non funziona ...? –

risposta

6

La risposta era dovuta a caratteri nascosti situati nel file lessons.db.

L'errore mostrato non ha avuto nulla a che fare con questo e vorrei ringraziare tutti coloro che hanno avuto il tempo di dare i loro due pence.

0

ho due cose per voi:

  1. Quando si dice: "so che è un sacco di codice, ma non posso capire perché questo sta accadendo tutto ad un tratto, letteralmente in un unico aggiornamento senza alcuna modifica al codice, anche se passo indietro alle versioni precedenti che funzionavano anche in questo caso ". Vorrei chiedere se stai programmando il tuo codice PHP tramite un browser? Se è così, a volte la cache ti rovinerà e trovo molto più facile sviluppare i miei modelli PHP attraverso l'interfaccia della riga di comando di PHP. Se questo non è il tuo caso, forse prendi in considerazione di spegnere completamente la cache del tuo browser durante lo sviluppo.
  2. Penso che il problema riscontrato provenga da errori di sintassi nelle colonne delle funzioni pubbliche della classe Config. Penso che tu debba leggere la sintassi dei casi di commutazione http://php.net/manual/en/control-structures.switch.php qui noterai che hai usato il punto e virgola dopo le guardie del caso, dove dovresti aver usato semplicemente due punti. Inoltre non c'è bisogno di rompere; dopo il tuo ritorno, poiché il tuo codice non arriverà mai a questo punto ...

Spero che questo aiuti - buona fortuna ...

+0

I punti e virgola sono validi nei casi switch, come mostrato nella pagina che hai collegato: http://php.net/manual/en/control-structures.switch.php –

+1

Ah, okay :) Impari tutti i giorni. – kraenhansen

Problemi correlati