Monday 4 December 2017

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





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.php on
line
50




I
am calling the Class as
follows:




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: />");

print_r($db->query('theta', NULL,
NULL));

print("

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

print("

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

print("


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


print("

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




Here
is my
class.database.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





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 {
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




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;
}

}
?>


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:




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


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
*





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



When I
do:



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


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






first second third fourth first second third
fourth




So it is
clearly working 1 line before it.


class="post-text" itemprop="text">
class="normal">Answer



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



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.



No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...