13 Replies - 5848 Views - Last Post: 08 May 2012 - 08:35 AM Rate Topic: -----

#1 SilverComet  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 20
  • Joined: 01-May 12

Catchable fatal error: Object of class could not be convert

Posted 01 May 2012 - 04:48 PM

I'm trying to run the code below and getting the error

[quote=php]Catchable fatal error: Object of class Connection could not be converted to string[/quote]

Ok so I am *incredibly* new to all this and am just running through the PHP OOP manual, I'm trying to make a very basic class just to learn on. Starting with the basics and expanding. I know my code isn't very good, so please feel free to *gently* point me in the right direction so I can try and improve. I know it isn't very good, and am not trying to pass myself off as an expert, so don't take offense at my garbage, please! :bigsmile:

That said....

I have 1 row in the table this is querying, but am still having issues, I know it's something really simple that I don't know/understand, and it's frustrating me that my own stupidity is getting in the way. I've spent the last few hours scratching my head on it.

The class

<?php
/*******************************
*	Created: 30/04/2012
*******************************/

class Connection
{
    protected $link;
    private $qcondition;
    private $outputQuery;
    
    
    private function connect()
    {
	// setting username and password here as, per installation will always be using same database for this small project.
	$server		= "127.0.0.1";
	$username 	= "root";
	$password	= "";
	$database	= "example";
	
        $this->link = mysqli_connect($server, $username, $password);
        mysqli_select_db($this->link, $database);
    }
    
    public function escape($string, $replace)
    {
	return mysqli_real_escape_string($this->link, $string);
	
	if($replace != 0)
	$string = str_replace("\"", "", $string);
	$string = str_replace("\\", "", $string);
	
	return $string;
    }


    
    public function query($query)
    {
	$this->connect(); // Connect always, as per PHP manual if connection exists will use it anyway.
	
	// escaping all data.	
	$query = $this->escape($query, 1);
	
	$queryresult = mysqli_query($this->link, $query) or die(mysqli_error($this->link));
	
	while ($queryrow = mysqli_fetch_array($queryresult))
	{
	    $this->outputQuery .= $queryrow['title'];
	}
	return $this->outputQuery;
    }
}
?>



the example:

<?php
include('database.php');

$test = new Connection;  

$test->query("SELECT * FROM blogentry WHERE id=1");


echo "$test";
?>



Sorry to be asking, what I'm sure is a really dumb question, I asked google first, but he's being moody today (nice birthday present to myself :rolleyes2:

Is This A Good Question/Topic? 0
  • +

Replies To: Catchable fatal error: Object of class could not be convert

#2 SilverComet  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 20
  • Joined: 01-May 12

Re: Catchable fatal error: Object of class could not be convert

Posted 01 May 2012 - 05:08 PM

Ok not sure how you edit your own posts (or if you can). I managed to get a working line using the below, feel a bit of a prat now replying to my own post - big no no on every other forum I've been on, so um, sorry. :sad2:

<?php
/*******************************
*	Created: 30/04/2012
*	By: Benjamin Faulkner
*******************************/

class Connection
{
    protected $link;
    private $qcondition;
    private $outputQuery;
    
    
    private function connect()
    {
	// setting username and password here as, per installation will always be using same database for this small project.
	$server		= "127.0.0.1";
	$username 	= "root";
	$password	= "";
	$database	= "intrepid";
	
        $this->link = mysqli_connect($server, $username, $password);
        mysqli_select_db($this->link, $database);
    }
    
    public function escape($string, $replace)
    {
	mysqli_real_escape_string($this->link, $string);
	
	if($replace != 0)
	$string = str_replace("\\'", "", $string);
	$string = str_replace("'", "", $string);	
	return $string;
    }


    
    public function query($query)
    {
	$this->connect(); // Connect always, as per PHP manual if connection exists will use it anyway.
	
	// escaping all data.	
	$query = $this->escape($query, 0);
	
	$this->outputQuery = mysqli_query($this->link, $query) or die(mysqli_error($this->link));
	
	return $this->outputQuery;
    }
}
?>



<?php
include('database.php');

$test = new Connection;  

$hello = $test->query("SELECT * FROM 'blogentry' WHERE id='1'");
while ($pro_sel = mysqli_fetch_object($hello))
{
    $testout = $pro_sel->title;
}
echo "$testout";
?>



However I'm pretty sure that

    public function escape($string, $replace)
    {
	mysqli_real_escape_string($this->link, $string);
	
	if($replace != 0)
	$string = str_replace("\\'", "", $string);
	$string = str_replace("'", "", $string);	
	return $string;
    }



Is doing nothing if $replace is set to 0, as it's adding slashes then immediately removing them, if I set it to 1 however it errors, so is there any reason why I'm doing this? I originally wanted to protect from injection with this.
Was This Post Helpful? 0
  • +
  • -

#3 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3480
  • View blog
  • Posts: 10,027
  • Joined: 08-June 10

Re: Catchable fatal error: Object of class could not be convert

Posted 01 May 2012 - 10:22 PM

View PostSilverComet, on 02 May 2012 - 01:48 AM, said:

the example:
<?php
include('database.php');

$test = new Connection;  

$test->query("SELECT * FROM blogentry WHERE id=1");

echo "$test";
?>


as you might have found out, echoing an object ($test) without a __toString() method causes that error.


View PostSilverComet, on 02 May 2012 - 02:08 AM, said:

Is doing nothing if $replace is set to 0, as it's adding slashes then immediately removing them, if I set it to 1 however it errors, so is there any reason why I'm doing this? I originally wanted to protect from injection with this.

I donít know about your reasons to do that, but you should definitely look into Prepared Statements. they make SQL Injection impossible (and the whole escaping stuff unnecessary).
Was This Post Helpful? 2
  • +
  • -

#4 SilverComet  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 20
  • Joined: 01-May 12

Re: Catchable fatal error: Object of class could not be convert

Posted 02 May 2012 - 08:15 AM

Thanks Dormilich, Your name keeps popping up in recommendations so I'm going to take that away and read it over the next couple of days (looks cryptic at the moment!)
Was This Post Helpful? 0
  • +
  • -

#5 SilverComet  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 20
  • Joined: 01-May 12

Re: Catchable fatal error: Object of class could not be convert

Posted 02 May 2012 - 10:12 AM

Ok I've taken a look at all the documentation I can find and am baffled as to how you would use this for OOP?

Ideally I want the query() functon to require no pre-processing. So that there is no chance of me forgetting to user the bind_param()

Additionally this seems to require all results in the bind_param() line, for example

bind_param("Name here", "Value here")


The only way I can see to use a single function for the queries is to run it through a for-loop (which I was doing, but that seems to only work with PDO which causes other issues.

bindParam(1, "Name here")
bindParam(2, "Value Here")


Issue with the above is, that if I do this, it doesn't accept

$query->bindParam


I know you must all be getting sick of me by now, Sorry :/

full (erroring) code:

<?php
/*******************************
*	Created: 30/04/2012
*******************************/

class Connection
{
    protected $link;
    private $qcondition;
    private $outputQuery;
    
    
    private function connect()
    {
	// setting username and password here as, per installation will always be using same database for this small project.
	$server		= "127.0.0.1";
	$username 	= "root";
	$password	= "";
	$database	= "intrepid";
	
        $this->link = mysqli_connect($server, $username, $password);
        mysqli_select_db($this->link, $database);
    }
    
    public function rowcount($result)
    {
	return mysqli_num_rows($result);
    }
    
    public function escape($string, $replace)
    {
	$string = mysqli_real_escape_string($this->link, $string);
	
	return $string;
    }

    public function bigbang($input, $separator, $expected)
    {
	$input = explode($separator, $input);
	
	if((count($input)) != $expected)
	{
	print "Sorry, the query returned a different number of variables to columns. Expected: " . $expected . " Separator: " . $separator . "<br><br>Array: ";
	print_r($input);
	}
	else
	{
	return $input;
	}
    }
    
    public function query($query, $data, $separator)
    {
	$this->connect(); // Connect always, as per PHP manual if connection exists will use it anyway.
	
	// exploding data
	$expected = substr_count($query, '?');
	$data = $this->bigbang($data, $separator, $expected);
	
	$query = $this->link->prepare($query);
	
	$i = 0;	
	foreach($data as $value)
	{
	    $query->bind_param($i, $v);
	    
	    $v = $value;
	    $query->execute();
	    
	    $i++
	}   

	return $this->outputQuery;
    }
}
?>

Was This Post Helpful? 0
  • +
  • -

#6 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3480
  • View blog
  • Posts: 10,027
  • Joined: 08-June 10

Re: Catchable fatal error: Object of class could not be convert

Posted 02 May 2012 - 04:34 PM

yea, Iíve found MySQLi always a bit hard to extend.

nevertheless,
- why mysqli_select_db()? for a simple query passing the DB name to the constructor is enough:

PHP said:

Note:

This function should only be used to change the default database for the connection. You can select the default database with 4th parameter in mysqli_connect().


then, either you go the standard query route or you do Prepared Statements, but donít mingle both together.

next, I know the function footprint of bind_param() is a little bit odd (and thatís probably why you use it wrong). you call that method once and pass it all parameters (and the combined data type as first parameter).

execute() only needs to be called once (i.e. not in a loop)

and yes, you canít mix PDO and MySQLi.
Was This Post Helpful? 0
  • +
  • -

#7 SilverComet  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 20
  • Joined: 01-May 12

Re: Catchable fatal error: Object of class could not be convert

Posted 03 May 2012 - 11:30 PM

Thanks for all the help so far, MySQLi documentation seems quite easy to find, PDO isn't so easy minus the original manual (which parts I get, others I don't, usually I reference 4 or 5 sources until it clicks, then move on).

Which would you recommend I use? Do I need something special to use PDO on a server? By this I mean do most servers support it?

Next question, my idea of having a class where one function can do almost any query, is that the right way to go about it? I can't see how it's compatible with bind_param as I don't know the number of the arguements.

I'm very rarely (if ever) going to call the same query more than once in my project, and I'd like to reduce the garbage on the code page itself, so the idea of this was to make any query a 1 line affair with all the hard work done on the class page (for example, I'd like to build on to it that whenever someone "UPDATE"s or "INSERT"s in a particular table that the class will record that action in order to make it easy for an admin to authorise the post without it being published, this would work well for things like comments, too).

Incase I don't make any sense, I've explained what I'm trying to do in the block below, I've checked online and found a few stackoverflow questions, helpfully the answers were "I never managed it despite trying, probably doable though".

    public function query($query, $data, $separator)
    {
	$this->connect(); // Connect always, as per PHP manual if connection exists will use it anyway.
	
	// exploding data
	$expected = substr_count($query, '?'); //this is checking for me how many question marks there are, ie how many columns should be filled.

	$data = $this->bigbang($data, $separator, $expected); // exploding the data, I haven't changed this function from before, all it does is separate the data and compare the number of strings returned to the number expected, then sends it back if it is correct, it may need work to remove the ability for a simple ";" to cause an extra string..essentially I've just made the injections less severe here rather than do anything useful
	

	$query = $this->link->prepare($query); // prepare, I'm not entirely sure what this actually does but read the manual and learnt how to use it at least
	
	
	// all of this is wrong
	$i = 1;	//setting our "i" number
	foreach($data as $value)
	{
	    $query->bind_param($i, $value);
	    
	    // debug
	    print $i;
	    print $value;

	    $i++;
	}   
	
	$query->execute();
	
	return $this->outputQuery;
    }



I took your advice on the mysqli_connect as well, and removed the extra db command.

I understand now that bind_param() only can work when you give it all the arguements in one go, which wont work for my intentions. I wrote this thinking about bindParam (I read them at the same time, brain had a melt down). bindParam seems to work with this sort of design.

// from php pdo manual
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $value);



If this should be in a separate thread now, please let me know, I've not subscribed to a forum for this sort of thing in many years, I only come here and bother people when I'm starting to rip my hair out!

From what little I've read of PDO it seems a much harder iteration of PHP to understand, so I'm thinking I should maybe stick with mysqli until I understand OOP, and then work on PDO? Is this even possible in MySQLi, and more importantly should it be?

I hope you don't feel I'm trying to get you to do it for me, I'm just trying to cope with the basics and then hopefully, my knowledge will go leaps and bounds once I've got a hang of it.
Was This Post Helpful? 0
  • +
  • -

#8 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3480
  • View blog
  • Posts: 10,027
  • Joined: 08-June 10

Re: Catchable fatal error: Object of class could not be convert

Posted 04 May 2012 - 12:15 AM

View PostSilverComet, on 04 May 2012 - 08:30 AM, said:

I understand now that bind_param() only can work when you give it all the arguements in one go, which wont work for my intentions. I wrote this thinking about bindParam (I read them at the same time, brain had a melt down). bindParam seems to work with this sort of design.

// from php pdo manual
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $value);


bindParam() is a PDO method, not a MySQLi method. hence it wonít work.

View PostSilverComet, on 04 May 2012 - 08:30 AM, said:

From what little I've read of PDO it seems a much harder iteration of PHP to understand, so I'm thinking I should maybe stick with mysqli until I understand OOP, and then work on PDO? Is this even possible in MySQLi, and more importantly should it be?

on the contrary, PDO is easier to iterate since it supports PHPís iteration system. i.e. you can use foreach() directly on a PDO result set. MySQLi works with a for()/while() loop.

btw. MySQLiís procedural style is just a helper construct to aid people coming from mysql_* functions. MySQLi is as OOP as PDO.

// PDO
$ps = $pdo->prepare($sql);
$ps->bindValue("param2", $value2, PDO::PARAM_STR);
$ps->bindValue("param1", $value1, PDO::PARAM_INT);
$ps->execute();
foreach ($ps as $row)
{
    echo $row['column'];
}

// MySQLi
$ps = mysqli->prepare($sql);
$ps->bind_param("is", $value1, $value2);
$ps->execute();
// otherwise you have next to no fetch options:
$res = $ps->get_result();
// foreach is supported as of PHP 5.4+
while ($row = $res->fetch_assoc())
{
    echo $row['column'];
}



View PostSilverComet, on 04 May 2012 - 08:30 AM, said:

Incase I don't make any sense, I've explained what I'm trying to do in the block below, I've checked online and found a few stackoverflow questions, helpfully the answers were "I never managed it despite trying, probably doable though".


without reposting the code.
- the connect() call does not belong here, it belongs in the Constructor. you could even think about a Singleton or Factory pattern to call it only once in the script.

- bind_param(), as has been already said, this function must only be called once with all parameters. period. you could use call_user_func_array() to make it work with an array of parameters. this is one of the main reasons I donít use MySQLi, binding parameters is a pain in the ***.

View PostSilverComet, on 04 May 2012 - 08:30 AM, said:

Which would you recommend I use? Do I need something special to use PDO on a server? By this I mean do most servers support it?


PDO is a core module in PHP (though only with the sqlite driver). every sensible host provider has both MySQLi and PDO(mysql) installed.

pros & cons:

PDO
+ can use Exceptions for error handling
+ uses PHPís iteration
+ simple, straightforward Interface
+ can use different databases (not only MySQL)
- itís a Data Access Abstraction Layer. itís not meant to fully support every possibility of a database

MySQLi
+ fully supports the MySQL database
+ procedural Interface
* PHP iteration only as of PHP 5.4+
- some queer methods, esp. with Prepared Statements (e.g. bind_param())
- only supports MySQL
Was This Post Helpful? 1
  • +
  • -

#9 SilverComet  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 20
  • Joined: 01-May 12

Re: Catchable fatal error: Object of class could not be convert

Posted 07 May 2012 - 10:25 AM

in update to this, I updated my code as follows:

<?php
/*******************************
*	Created: 30/04/2012
*******************************/

class Connection
{
    protected $dbh;
    protected $ps;
    private $qcondition;
    private $outputQuery;
    
    
    function __construct()
    {
	try
	{
	    $this->dbh = new PDO('mysql:host=127.0.0.1;dbname=intrepid', 'root', '');
	    
	}
	catch(PDOException $e)
	{
	    echo $e->getMessage();
	}
    }
    
    public function disc()
    {
	$this->dbh = NULL;
    }
    
    public function objectFetch($sql)
    {
	$this->ps = $this->dbh->prepare($sql);
	
	if(func_num_args() > 1)
	{
	    $i = 1;
	    $as = array_splice(func_get_args(), 1);
	    foreach($as as $argument)
	    {
		$this->ps->bindValue($i, $argument, PDO::PARAM_INT);
		$i++;
	    }
	}
	
	
	$this->ps->execute();
	$result = $this->ps->fetch(PDO::FETCH_OBJ);
	
	return $result;
    }
}
?>


I still need to add a try/catch to the latter half but I'm still learning that.

now my output test page is:

<?php
include('database.php');

$test = new Connection;  

echo 'testing select: <br> ';
$query = $test->objectFetch("SELECT * FROM pages WHERE id=? AND url=?", '1', '2');

echo $query->title;
?>



but my question is: is this what you would do? is there any improvements I can make? Thank you for your time so far, as you can probably tell I've improved a lot with all the help! (least I think so.. :innocent: )
Was This Post Helpful? 0
  • +
  • -

#10 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3480
  • View blog
  • Posts: 10,027
  • Joined: 08-June 10

Re: Catchable fatal error: Object of class could not be convert

Posted 07 May 2012 - 10:24 PM

improvements:
- set PDO error handling to exceptions (this needs to be done manually)
- donít catch inside the class* (you catch exceptions where you can handle the cause)
- LIMIT your SQL statement (you query for all matching results, but return only one)
- PDO can destruct itself, no need to do that manually
- donít connect as "root", thatís highly risky



* assuming your connection would fail, youíll get a "null or not an object" error on line #34
Was This Post Helpful? 1
  • +
  • -

#11 SilverComet  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 20
  • Joined: 01-May 12

Re: Catchable fatal error: Object of class could not be convert

Posted 08 May 2012 - 07:39 AM

improvements:
- set PDO error handling to exceptions (this needs to be done manually).
-- Will come back to you after some reading.

- donít catch inside the class* (you catch exceptions where you can handle the cause)
-- Don't follow on this one, will research and come back to you.

- LIMIT your SQL statement (you query for all matching results, but return only one)
-- Understood, this would probably be more clear if I copied the database, there was only 1 matching result, it's just a very simple test query to make sure it all works. I will test it with a LIMIT option though.

- PDO can destruct itself, no need to do that manually
-- Got it, will remove!

- donít connect as "root", thatís highly risky
-- It's my EASYPHP installation where I'm building this, hence the lazy approach to security of accounts, if it was live it'd have it's own user without drop permissions.
Was This Post Helpful? 0
  • +
  • -

#12 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3480
  • View blog
  • Posts: 10,027
  • Joined: 08-June 10

Re: Catchable fatal error: Object of class could not be convert

Posted 08 May 2012 - 07:57 AM

View PostSilverComet, on 08 May 2012 - 04:39 PM, said:

- donít connect as "root", thatís highly risky
-- It's my EASYPHP installation where I'm building this, hence the lazy approach to security of accounts, if it was live it'd have it's own user without drop permissions.

what about the permissions for ALTER & CREATE. those can be as devastating as DROP.
Was This Post Helpful? 0
  • +
  • -

#13 SilverComet  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 20
  • Joined: 01-May 12

Re: Catchable fatal error: Object of class could not be convert

Posted 08 May 2012 - 08:13 AM

*checks cpanel* Yep remembered those, it has been many years since I last made a user! :bigsmile:

is there anywhere better to go for error handling documentation than the manual page: http://php.net/manua...or-handling.php ?

I'd like to read up on what to do in classes etc. :)
Was This Post Helpful? 0
  • +
  • -

#14 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3480
  • View blog
  • Posts: 10,027
  • Joined: 08-June 10

Re: Catchable fatal error: Object of class could not be convert

Posted 08 May 2012 - 08:35 AM

the Manual page tells you how the code goes, but for an explanation how error/exception handling works, youíll have to find tutorials (not necessarily specific to PHP).

this one seems sensible.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1