it-swarm-pt.tech

PHP: Erro fatal: chamar uma função de membro em um não-objeto

Obtendo um erro muito estranho aqui, estou escrevendo uma classe de banco de dados flatfile e tudo funcionou bem até que eu atualizei e agora estou constantemente recebendo esta mensagem:

Erro fatal: chama um nome de função de membro () em um não-objeto em / home/reithg/public_html/test/engine/class.database.php on-line - 5

Estou chamando a classe da seguinte maneira:

<?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));
?>

Aqui está o meu 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;
        }
    }
?>

Eu sei que é muito código, mas não consigo entender por que isso está acontecendo de repente, literalmente em uma atualização sem nenhuma alteração no código. Mesmo se eu voltar para versões anteriores que também funcionaram, isso está acontecendo.

Quando tento fazer:

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

Retorna:

Erro fatal detectável: Objeto da classe A coluna não pôde ser convertida em string em / home/reithg/public_html/test/engine/class.database.php * na linha 50 *

O que mostra que estou executando name() em um membro da classe Column que possui um método público chamado name()

Quando eu faço:

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

retorna (uma palavra por vez, como em um loop foreach);

primeiro segundo terceiro quarto primeiro segundo terceiro quarto

Portanto, está claramente trabalhando uma linha antes dela.

12
George Reith

A resposta foi devido a caracteres ocultos localizados no arquivo aulas.db.

O erro mostrado não teve nada a ver com isso e gostaria de agradecer a todos que se dedicaram a dar seus dois centavos.

7
George Reith

Eu tenho duas coisas para você:

  1. Quando você diz: "Eu sei que é muito código, mas não consigo entender por que isso está acontecendo de repente, literalmente em uma atualização sem nenhuma alteração no código. Mesmo se eu voltar para versões anteriores que também funcionaram, isso é acontecendo ". Gostaria de perguntar se você está programando em seu código PHP através de um navegador? Em caso afirmativo, algumas vezes o cache irá interferir com você, e acho muito mais fácil desenvolver meu PHP modela a interface de linha de comando PHP. Se isso não for o seu caso, considere desativar o cache do navegador completamente durante o desenvolvimento).
  2. Eu acho que o problema que você está enfrentando vem de erros de sintaxe nas colunas de função pública da sua classe Config. Eu acho que você precisa ler a sintaxe dos casos de opção http://php.net/manual/en/control-structures.switch.php aqui você notará que usou ponto e vírgula após protetores de caso, onde você deveria ter usado apenas dois pontos. Também não há necessidade de quebrar; depois que você retornar, já que seu código nunca chegará a esse ponto ...

Espero que isso ajude. Boa sorte ...

0
kraenhansen