PHP:致命错误:调用非对象上的成员函数Call to a member function on a non-object

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

本问题已经有最佳答案,请猛点这里访问。

这里出现了一个非常奇怪的错误,我正在编写一个平面文件数据库类,在刷新之前,这一切都正常工作,现在我不断收到以下消息:

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

我给班级打电话如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?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));
?>

这是我的class.database.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<?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)."

"
;
            return $output;
        }

        private function escapeData($data)
        {
            $search = array('\', '"',"'", '\\0', '
', $this->_config->delimiter());
            $replace = array('
\\\', '"',"\'", '\\0', '\
', '\'.$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 =="
" || $char =="
"){
                        $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类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?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类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?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;
        }
    }
?>

我知道这是很多代码,但我不明白为什么这会突然发生,实际上是一次刷新而没有对代码进行任何更改。即使我回溯到以前的版本,也会发生这种情况。

当我试图这样做时:

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

它返回:

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*

这表明我正在类列的一个成员上执行name(),该成员具有一个名为name()的公共方法。

当我这样做的时候:

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

它返回(一次返回一个单词,就像在foreach循环中一样);

first second third fourth first second third fourth

所以很明显,它在它前面有一条线在工作。


答案是由于lessons.db文件中的隐藏字符造成的。

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


我有两件事要告诉你:

  • 当你说:"我知道这是很多代码,但我不明白为什么这会突然发生,字面意思是在一次刷新中没有任何代码更改。即使我回溯到以前的版本,也会发生这种情况,"我想问你是不是在通过浏览器编写PHP代码?如果是这样的话,有时候缓存会给你带来麻烦,我发现通过php命令行界面开发php模型要容易得多。如果这不适合您,可以考虑在开发时完全关闭浏览器缓存。
  • 我认为您遇到的问题来自配置类的公共函数列中的语法错误。我认为您必须阅读一下switch cases的语法http://php.net/manual/en/control-structures.switch.php这里您会注意到您在case guards后面使用了分号,在这里您应该只使用冒号。也没有必要中断;在您返回之后,因为您的代码无论如何都不会达到这一点…
  • 我希望这有帮助-祝你好运…