PHP:致命错误:调用非对象上的成员函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8519011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 04:54:10  来源:igfitidea点击:

PHP: Fatal error: Call to a member function on a non-object

phpfatal-error

提问by George Reith

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:

在这里遇到一个非常奇怪的错误,我正在编写一个平面文件数据库类,这一切正常,直到我刷新,现在我不断收到此消息:

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

致命错误:在第50行的/home/reithg/public_html/test/engine/class.database.php 中的非对象上调用成员函数 name()

I am calling the Class as follows:

我按如下方式调用类:

<?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
<?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;
        }
    }
?>
these
<?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;
            }   
        }
    }
?>
nulls',"don't, forget quotes"); print("input: "); print_r($testInput); echo("<br />output: "); print($db->addRow($testInput)); ?>

Here is my class.database.php

这是我的class.database.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;
        }
    }
?>

class.config.php

类.config.php

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

class.column.php

类.column.php

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

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.

我知道这是很多代码,但我无法弄清楚为什么会突然发生这种情况,实际上是在一次刷新中而不对代码进行任何更改。即使我回溯到同样有效的早期版本,这种情况也会发生。

When I attempt to do:

当我尝试做:

##代码##

It returns:

它返回:

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*

可捕获的致命错误:50 行*在/home/reithg/public_html/test/engine/class.database.php* 中无法将类 Column 的对象转换为字符串

Which shows that I am performing name()on a member of class Column which has a public method called name()

这表明我正在name()对 Column 类的一个成员进行表演,该成员有一个名为name()

When I do:

当我做:

##代码##

it returns (one word per time as it is in a foreach loop);

它返回(每次一个单词,因为它在 foreach 循环中);

first second third fourth first second third fourth

第一个第二个第三个第四个第二个第三个第四个

So it is clearly working 1 line before it.

所以它显然在它之前工作 1 行。

采纳答案by George Reith

The answer was due to hidden characters located in the lessons.dbfile.

答案是由于位于classes.db文件中的隐藏字符。

The error shown had nothing to do with this and I would like to thank everyone who took the time to give their two pence.

显示的错误与此无关,我要感谢所有花时间付出两便士的人。

回答by kraenhansen

I have two things for you:

我有两件事要给你:

  1. When you say: "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." I would like to ask if you are programming on you PHP code through a browser? If so, sometimes the cache will mess with you, and I find it much easier to develop my PHP models through the PHP command-line interface. If this is not for you, maybe consider turning your browsers cache completely off when developing.
  2. I think the problem you are experiencing comes from syntax errors in the public function columns of your Config class. I think you have to read up on the syntax of switch-cases http://php.net/manual/en/control-structures.switch.phphere you will notice that you have used semicolons after case guards, where you should have used simply colons. Also there is no need to break; after you return, as your code will never reach this point anyway ...
  1. 当您说:“我知道有很多代码,但我无法弄清楚为什么会突然发生这种情况,实际上是在一次刷新中而不对代码进行任何更改。即使我回溯到同样有效的早期版本也是如此正在发生。” 我想问一下您是否正在通过浏览器对您的PHP代码进行编程?如果是这样,有时缓存会弄乱你,我发现通过 PHP 命令行界面开发我的 PHP 模型要容易得多。如果这不适合您,可以考虑在开发时完全关闭浏览器缓存。
  2. 我认为您遇到的问题来自 Config 类的公共函数列中的语法错误。我认为你必须阅读 switch-cases http://php.net/manual/en/control-structures.switch.php的语法,你会注意到你在 case guards 之后使用了分号,你应该有简单地使用冒号。也没有必要打破; 在您返回后,因为您的代码无论如何都不会到达这一点......

I hope this helps - good luck ...

我希望这会有所帮助 - 祝你好运......