Object of class "story" could not be converted to string - php

I'm having an issue with a bit of my code; it was working fine until I added a single new function, now it's not working at all--it's sending "Catchable Fatal Error: Object of class story could not be converted to string". I've removed the function from the class, and still am getting that error.
<?php
class story extends StarMap
{
function __construct($X, $Y, $db)
{
$this->X = $X;
$this->Y = $Y;
$this->db = $db;
parent::__construct($this->X, $this->Y, $this->db);
#echo $this->AddStoryElement();
}
function AddStoryElement()
{
#$array = $this->selectStoryArray();
$array = array('1');
$top = mt_rand(0, 95);
$left = mt_rand(0, 95);
$html = "\n <div class='star' style='top:{$top}%; left:'{$left}%;' href='#' id='{$array[0]}'>";
$html .= "<img src='assets/stars/unknown.png' width='25' height='25'>";
$html .= "</div>";
return $html;
}
function selectStoryArray()
{
$sql = "SELECT story_id, story_type, story_content, story_url FROM storymaptopdown";
$que = $this->db->query($sql);
try {
$que->execute();
while($row = $que->fetch(PDO::FETCH_BOTH))
{
return $row;
}
}catch(PDOException $e) {}
}
}
?>
This is where the class is called
require_once('lib/bootstrap.php');
echo '<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>'.
'<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>'.
'<script src="js/hoverintent.js" type="text/javascript"></script>'.
'<script src="js/jquery.tooltip.js" type="text/javascript"></script>'.
'<script src="js/js.js" type="text/javascript"></script>'.
$map = new story($_GET['X'], $_GET['Y'], $db);
return true;

You are concatenating the result of the $map = new story() line to the previous string (the one starting with the echo). You probably meant to put a ; there not an ..
Or if you did wanted to concatenate it, define the magic __toString() method on your class.

Related

php Declare a variable by type held in a string

I am trying to declare an object by the value held in a string. So if a string holds 'Class1' i want to declare it by type Class1.
Something like this
$CT = "Class1";
if (class_exists($CT))
$MyClass = new Type($CT);
I can do something like the following, but would rather do it as above if possible.
if (isset($_GET["CT"]))
$CT = $_GET["CT"];
else
$CT = "Class1";
echo "CT = " . $CT . "<br>";
switch ($CT)
{
case "Class1":
$MyClass = new Class1;
break;
case "Class2":
$MyClass = new Class2;
break;
default:
$MyClass = new Class1;
}
echo $MyClass->Result();
class Class1
{
function Result()
{
return "I am Class 1";
}
}
class Class2
{
function Result()
{
return "I am Class 2";
}
}
You can use variables after the new keyword:
$CT = "Class1";
if (class_exists($CT))
$MyClass = new $CT();
You can most assuredly create a class instance by its name alone, so your code would be
<?php
if (isset($_GET["CT"]))
$CT = $_GET["CT"];
else
$CT = "Class1";
echo "CT = " . $CT . "<br>";
$instance = new $CT();
echo $instance->Result();
class Class1
{
function Result()
{
return "I am Class 1";
}
}
class Class2
{
function Result()
{
return "I am Class 2";
}
}
See it in action here

Passing variables from one class to an other in PhP

Hello I am trying to build my first restful web service and im using the instruction from lorna jane mitchell blog.
If the req comes through this Url : http://localhost:8888/lorna/index.php/tree/getpath?node_id=75
i call the function getpath passing node_id
The function get path looks like this :
class NestedSet
{
public function getPath($id) {
$sql = "SELECT p." . $this->pk . ", p." . $this->name . " FROM ". $this->table . " n, " . $this->table . " p WHERE n.lft BETWEEN p.lft AND p.rgt AND n." . $this->pk ." = " . $id . " ORDER BY p.lft;";
$result = $this->db->query($sql);
if ($result->num_rows == 0) {
return $this->error(1, true);
}
$path = array();
$i = 0;
while ($row = $result->fetch_assoc()) {
$path[$i] = $row;
$i++;
}
return $path;
}
}
Now i want to pass this variable $path to the class JsonView that looks like this :
class JsonView extends ApiView {
public function render($path) {
header('Content-Type: application/json; charset=utf8');
echo json_encode($path);
return true;
}
}
class ApiView {
protected function addCount($data) {
if(!empty($data)) {
// do nothing, this is added earlier
} else {
$data['meta']['count'] = 0;
}
return $data;
}
}
Any Idea on how can I pass the variable $path or any other variable through this JsonView Class.
Thank you very much for your time :)
UPDATE This is the code for creating the nested class object
public function getAction($request) {
$data = $request->parameters;
if(isset($request->url_elements[2])) {
switch ($request->url_elements[2]) {
case 'getpath':
$id = $data['node_id'];
$nested = new NestedSet();
$nested->getPath($id);
$api = new JsonView();
$api->render($path);
break;
default:
# code...
break;
}
} else {
$nested = new NestedSet();
echo $nested->treeAsHtml();
}
}
Just create object of JsonView and then call the function render using that object.
$api = new JsonView;
$api->render($path);

PDO request within a class

Here is my class :
class ProfileLink {
function profileLink(PDO $pdo, $string, $i=0)
{
if ($i!=0) {
$link = $string . '-' . $i;
} else {
$link = $string;
}
$req = $pdo->prepare('SELECT link FROM users WHERE link = ?');
$req->execute(array($link));
$nb = $req->rowCount();
$req->closeCursor();
if ($nb > 0) {
$i++;
return profileLink($pdo, $string, $i);
} else {
return $link;
}
}
}
When I call the profileLink function from the class, it doesn't work, but if I call it outside the class, everything is ok. It might be a problem with the PDO, what do you think ?
require_once ('lib/profileLink.class.php');
$profileLink = new ProfileLink();
$link = $profileLink->profileLink($pdo, $string);
I would store the instance of PDO as a class property so that it can be easily accessed within the class. Note that my example uses slightly different syntax (modern PHP).
class ProfileLink {
protected $pdo;
public function __construct(PDO $pdo) {
$this->pdo = $pdo;
}
public function profileLink($string, $i=0)
{
if ($i!=0) {
$link = $string . '-' . $i;
} else {
$link = $string;
}
$req = $this->pdo->prepare('SELECT link FROM users WHERE link = ?');
$req->execute(array($link));
$nb = $req->rowCount();
$req->closeCursor();
if ($nb > 0) {
$i++;
return profileLink($string, $i);
} else {
return $link;
}
}
}
$profileLink = new ProfileLink($pdo);
2 Things:
here
return profileLink($pdo, $string, $i);
you are missing a $this, because it's no regular function but a class method:
return $this->profileLink($pdo, $string, $i);
And second, your method has the same name as the class (except of the first capital letter), and thus seems to be interpreted as constructor. I have just tested this:
class Test {
function test() {
echo "test";
}
}
$t = new Test();
And it outputs "test".
So you should rename your method to getLink or something similar.

PHP - Calling function inside another class -> function

I'm trying to do this:
class database {
function editProvider($post)
{
$sql = "UPDATE tbl SET ";
foreach($post as $key => $val):
if($key != "providerId")
{
$val = formValidate($val);
$sqlE[] = "`$key`='$val'";
}
endforeach;
$sqlE = implode(",", $sqlE);
$where = ' WHERE `id` = \''.$post['id'].'\'';
$sql = $sql . $sqlE . $where;
$query = mysql_query($sql);
if($query){
return true;
}
}
//
}//end class
And then use this function * INSIDE of another class *:
function formValidate($string){
$string = trim($string);
$string = mysql_real_escape_string($string);
return $string;
}
//
.. on $val. Why doesn't this work? if I write in a field of the form, it's not escaping anything at all. How can that be?
* UPDATE *
handler.php:
if(isset($_GET['do'])){
if($_GET['do'] == "addLogin")
{
$addLogin = $db->addLogin($_POST);
}
if($_GET['do'] == "addProvider")
{
$addProvider = $db->addProvider($_POST);
}
if($_GET['do'] == "editProfile")
{
$editProfile = $db->editProfile($_POST);
}
if($_GET['do'] == "editProvider")
{
$editProvider = $db->editProvider($_POST);
}
}
//end if isset get do
** The editProvider function works fine except for this :-) **
You need to instantiate that validate class and than once instantiated you will need to call that function in that class with your value parameters.
Inside your editProvider you can have:
$validator = new validate();
$val = $validator->formValidate($val);
If the above doesn't work, try the following:
$val = mysql_real_escape_string(trim($val));
and see if it works, if it does it has to do with the correct function not being called.
Not sure why you are so bent on using $this vs a static implementation. IMO, a static call makes this code much easier. If you really want access to $this->formValidatString() from your database class, you will have to do class database extends MyOtherClass.
Here is how easy it would be to do a static call:
class database {
public function editProvider($post)
{
$sql = "UPDATE tbl SET ";
foreach($post as $key => $val):
if($key != "providerId")
{
$val = MyOtherClass::formValidate($val);
$sqlE[] = "`$key`='$val'";
}
endforeach;
$sqlE = implode(",", $sqlE);
$where = ' WHERE `id` = \''.$post['id'].'\'';
$sql = $sql . $sqlE . $where;
$query = mysql_query($sql);
if($query){
return true;
}
}
}//end class
class MyOtherClass
{
public static function formValidate($string) {
if (strlen($string) < 1) {
throw new Exception('Invalid $string ' . $string . ');
}
$string = trim($string);
$string = mysql_real_escape_string($string);
return $string;
}
}
You don't need to have an instance for this purpose. Just do validate::formValidate($val);.

PHP OOP Class Help

I'm am unsure on how to move part of my code into a class.
<?php
class InfoTest {
private $info_results;
public function __construct() {
$dbc = get_dbc();
$info = $dbc->query ("SELECT info_id, info_title FROM text");
if ($dbc->error) {
printf("Error: %s\n", $dbc->error);
}
while ($info_row = $info->fetch_array())
{
$info_results[]= $info_row;
}
$info->free();
$this->info_results = $info_results;
}
public function setInfo() {
$this->info_results = $info_results;
}
public function getInfo() {
return $this->info_results;
}
public function __destruct() {
}
}
?>
<?php
$display = new InfoTest();
foreach ($display->getInfo() as $info_row) {
?>
<!-- html -->
<?php echo $info_row['info_title']."</a><br />"; ?>
<!-- html -->
Sub-Info:
<?php
$dbc = get_dbc();
$si_title = $dbc->query ("SELECT info_title FROM text WHERE info_id = ".$info_row['info_id']."");
if ($dbc->error) {
printf("Error: %s\n", $dbc->error);
}
$num =$si_title->num_rows;
$count = 0;
while ($sub_info = $si_title->fetch_array())
{
$sub_info_title = $sub_info['info_title'];
if ($count!=$num-1)
{
echo $sub_info_title." , ";
$count++;
}
else echo $sub_info_title;
}
?>
<!-- html -->
<?php } ?>
I'm unsure how to move the Sub-Info(code after Sub-Info:) into a class. Does it go in the same class as InfoTest, a class of its own, or doesn't go into a class at all?
Sub-Info Code:
<?php
$dbc = get_dbc();
$si_title = $dbc->query ("SELECT info_title FROM text WHERE info_id = ".$info_row['info_id']."");
if ($dbc->error) {
printf("Error: %s\n", $dbc->error);
}
$num =$si_title->num_rows;
$count = 0;
while ($sub_info = $si_title->fetch_array())
{
$sub_info_title = $sub_info['info_title'];
if ($count!=$num-1)
{
echo $sub_info_title." , ";
$count++;
}
else echo $sub_info_title;
}
?>
In your class you have already all information. So an alternative to a sql-query could be an additional method, which searches all titles with a special id in the private field info_results. E.g.:
public function getInfoTitles($info_id) {
$titles = array();
foreach ($this->info_results as $info_row) {
if ($info_row['info_id'] == $info_id)
$titles[] = $info_row['info_title'];
}
}
return $titles;
}
Your Sub-Info Code is then:
echo implode(', ', $display->getInfoTitles($info_row['info_id']));
The general idea of OOP is to couple data with methods that process that data. So, if you feel that some piece of your data are processed in the same way multiple times, it's a good idea to introduce a class that will incapsulate that data and logic.
Of course it emerges a lot of other questions: how many classes should one have, how should they interact with each other, which part of business logic should go in which class etc. There is no universal, always-true answer to that questions, but some general approaches to address that questions were developed: the design patterns. There are some books on the topic, one of the most known is Gang-of-Four (GoF) Design Patterns.
That's general thoughts on the topic. In your particular case, I would suggest you creating new class ItemInfo, so InfoTest class is responsible only for quering the DB and creating Instances of this new class.
class InfoTest {
private $items;
public function __construct() {
$this->items = new Array();
}
private function queryItems($itemId){
$dbc = get_dbc();
$info = $dbc->query("SELECT info_id, info_title FROM text");
if ($dbc->error) {
printf("Error: %s\n", $dbc->error);
}
while ($info_row = $info->fetch_array())
{
$item = new ItemInfo($info_row);
$this->items[] = $item;
}
$info->free();
}
public function getItems($itemId){
if (empty($this->items)){
$this->queryItems($itemId);
}
return $this->items;
}
/* Other functions. */
public function __destruct() {
}
}
Class ItemInfo{
private $id, $title;
function __construct(Array $params){
$this->id = $params['item_id'];
$this->title = $params['item_title'];
}
function getTitle(){
return $this->title;
}
function toString(){
retirn "I'm item {$this->id}, my title is {$this->title}";
}
}
And your code will be as simple as
$item_test = new ItemTest();
$items = $item_test->getItems($item_id);
$titles = array();
foreach ($items as $item){
//you may process your items in any way you need
$titles[] = $item->getTitle();
}
echo implode(',', $titles);

Categories