Jump to content

Iteration over $this and inheritance


tx34

Recommended Posts

Hello, I have two classes:

 

abstract class Serializable
{
public function serialize()
{
	foreach($this as $member => $value)
	{
		$publicObject->$member = $value;
	}
	return $publicObject
}
}

class ToSerialize extends Serializable
{
public function otherSerialize()
{
	foreach($this as $member => $value)
	{
		$publicObject->$member = $value;
	}
	return $publicObject
}
}

$foo = new ToSerialize();
$foo->serialize(); //This will return one thing
$foo->otherSerialize(); //This will return something different

 

Why does this happen?  :confused:

Link to comment
Share on other sites

alright,

 

<?php

abstract class A_JsonSerializable 
{
  
    public function toJson()
    {
        foreach($this as $member => $value)
        {
            $publicObject->$member = $value;
        }
        return json_encode($publicObject);
    }

}

abstract class A_Polygon extends A_JsonSerializable
{
    
    private static $objectCount_ = 0;
    private $id_;
    private $shapeType_;    
    protected $coordinates_;
    
    public function __construct($shapeType = "Polygon") 
    {
        $this->id_ = self::$objectCount_;
        self::$objectCount_++;
        $this->shapeType_ = $shapeType;
    }

    public function otherToJson()
    {
        foreach($this as $member => $value)
        {
            $publicObject->$member = $value;
        }
        return json_encode($publicObject);
    }
    
}

class Hexagon extends A_Polygon
{   
    
    public function __construct($sideLength, Point $initialPoint) 
    {
        parent::__construct("Hexagon");

        $a = $sideLength * cos(M_PI / 6);
        $b = $sideLength * sin(M_PI / 6);
        
        $this->coordinates_[] = $initialPoint;
        $this->coordinates_[] = new Point($this->coordinates_[0]->x_ - $a, 
                                         $this->coordinates_[0]->y_ - $b);
        $this->coordinates_[] = new Point($this->coordinates_[1]->x_,
                                         $this->coordinates_[1]->y_ - $side);
        $this->coordinates_[] = new Point($this->coordinates_[0]->x_,
                                         $this->coordinates_[2]->y_ - b);
        $this->coordinates_[] = new Point($this->coordinates_[0]->x_ + a,
                                         $this->coordinates_[2]->y_);
        $this->coordinates_[] = new Point($this->coordinates_[4]->x_,
                                         $this->coordinates_[1]->y_);
    } 
    
}

function println($string)
{
    print($string . "<BR>");
}

$hex = new Hexagon(10, new Point(50, 50));
println($hex->otherToJson());
println($hex->toJson());

?>

 

This gives the output:

 

{"id_":0,"shapeType_":"Hexagon","coordinates_":[{"x_":50,"y_":50},{"x_":41.3397459622,"y_":45},{"x_":41.3397459622,"y_":45},{"x_":50,"y_":45},{"x_":50,"y_":45},{"x_":50,"y_":45}]}

{"coordinates_":[{"x_":50,"y_":50},{"x_":41.3397459622,"y_":45},{"x_":41.3397459622,"y_":45},{"x_":50,"y_":45},{"x_":50,"y_":45},{"x_":50,"y_":45}]}

 

When I used Zend_Json::encode($publicObject) I get "null" for the toJson() call.

Link to comment
Share on other sites

Damnit, I'm sorry! I double checked it this time to make sure:

 

<?php

class Point
{
    public $x_;
    public $y_;
    
    public function __construct($x, $y)
    {
        $this->x_ = $x;
        $this->y_ = $y;
    }    
}

abstract class A_JsonSerializable 
{
  
    public function toJson()
    {
        foreach($this as $member => $value)
        {
            $publicObject->$member = $value;
        }
        return json_encode($publicObject);
    }

}

abstract class A_Polygon extends A_JsonSerializable
{
    
    private static $objectCount_ = 0;
    private $id_;
    private $shapeType_;    
    protected $coordinates_;
    
    public function __construct($shapeType = "Polygon") 
    {
        $this->id_ = self::$objectCount_;
        self::$objectCount_++;
        $this->shapeType_ = $shapeType;
    }

    public function otherToJson()
    {
        foreach($this as $member => $value)
        {
            $publicObject->$member = $value;
        }
        return json_encode($publicObject);
    }
    
}

class Hexagon extends A_Polygon
{   
    
    public function __construct($sideLength, Point $initialPoint) 
    {
        parent::__construct("Hexagon");

        $a = $sideLength * cos(M_PI / 6);
        $b = $sideLength * sin(M_PI / 6);
        
        $this->coordinates_[] = $initialPoint;
        $this->coordinates_[] = new Point($this->coordinates_[0]->x_ - $a, 
                                         $this->coordinates_[0]->y_ - $b);
        $this->coordinates_[] = new Point($this->coordinates_[1]->x_,
                                         $this->coordinates_[1]->y_ - $side);
        $this->coordinates_[] = new Point($this->coordinates_[0]->x_,
                                         $this->coordinates_[2]->y_ - b);
        $this->coordinates_[] = new Point($this->coordinates_[0]->x_ + a,
                                         $this->coordinates_[2]->y_);
        $this->coordinates_[] = new Point($this->coordinates_[4]->x_,
                                         $this->coordinates_[1]->y_);
    } 
    
}

function println($string)
{
    print($string . "<BR>");
}

$hex = new Hexagon(10, new Point(50, 50));
println($hex->otherToJson());
println($hex->toJson());

?>

Link to comment
Share on other sites

Ok, so it's riddled with Notices but is still outputting results.

 

PHP Notice:  Undefined variable: side in /home/thorpe/foo.php on line 70

Notice: Undefined variable: side in /home/thorpe/foo.php on line 70
PHP Notice:  Use of undefined constant b - assumed 'b' in /home/thorpe/foo.php on line 72

Notice: Use of undefined constant b - assumed 'b' in /home/thorpe/foo.php on line 72
PHP Notice:  Use of undefined constant a - assumed 'a' in /home/thorpe/foo.php on line 73

Notice: Use of undefined constant a - assumed 'a' in /home/thorpe/foo.php on line 73
PHP Strict Standards:  Creating default object from empty value in /home/thorpe/foo.php on line 49

Strict Standards: Creating default object from empty value in /home/thorpe/foo.php on line 49
{"id_":0,"shapeType_":"Hexagon","coordinates_":[{"x_":50,"y_":50},{"x_":41.339745962156,"y_":45},{"x_":41.339745962156,"y_":45},{"x_":50,"y_":45},{"x_":50,"y_":45},{"x_":50,"y_":45}]}<BR>PHP Strict Standards:  Creating default object from empty value in /home/thorpe/foo.php on line 23

Strict Standards: Creating default object from empty value in /home/thorpe/foo.php on line 23
{"coordinates_":[{"x_":50,"y_":50},{"x_":41.339745962156,"y_":45},{"x_":41.339745962156,"y_":45},{"x_":50,"y_":45},{"x_":50,"y_":45},{"x_":50,"y_":45}]}<BR>

 

As for why your getting different output. It's a bit hard to explain. But if you declared all your properties within the Pont object it would be fine. Basically, when you are looping through $this it is picking up the properties of the class your function is defined in at the time it is defined.

Link to comment
Share on other sites

That is too bad, I was hoping I could just define it in one place, since I was planning to use it in a few different classes. I didn't even know I had warnings turned off. I am new to php, I am a C++ programmer. However after turning them on I do not not get quite as many warnings as you:

 

Notice: Undefined variable: side in /home/vol14/byethost22.com/b22_9075969/htdocs/forte/test.php on line 70

 

Notice: Use of undefined constant b - assumed 'b' in /home/vol14/byethost22.com/b22_9075969/htdocs/forte/test.php on line 72

 

Notice: Use of undefined constant a - assumed 'a' in /home/vol14/byethost22.com/b22_9075969/htdocs/forte/test.php on line 73

{"id_":0,"shapeType_":"Hexagon","coordinates_":[{"x_":50,"y_":50},{"x_":41.3397459622,"y_":45},{"x_":41.3397459622,"y_":45},{"x_":50,"y_":45},{"x_":50,"y_":45},{"x_":50,"y_":45}]}

{"coordinates_":[{"x_":50,"y_":50},{"x_":41.3397459622,"y_":45},{"x_":41.3397459622,"y_":45},{"x_":50,"y_":45},{"x_":50,"y_":45},{"x_":50,"y_":45}]}

Link to comment
Share on other sites

I was planning on replying earlier but I was having a fight to the death with my router. The C++ compiler is a lot less forgiving of my stupider moments, unlike php which seems to happily run no matter what garbage you give it. I came up with a solution for encoding private members, since I couldn't find something to do it for me. Although I probably wasn't looking hard enough or I was just being stupid again. It may not be the best solution, and the functions don't protect against user error, but it seems to be getting the job done so far.

 

<?php

abstract class A_JsonSerializable 
{
    abstract public function toJson();
    
    protected function element($name, $object)
    {
        $json = "\"" . $name . "\":";
        $json .= $this->processObject($object);
        return $json;
    }
    
    protected function native($name, $object)
    {
        $json = "\"" . $name . "\":";
        $json .= json_encode($object);
        return $json; 
    }
    
    private function processObject($object)
    {
        $json = "";
        if(is_array($object))
        {
            $json .= "[";
            for($i = 0; $i < count($object) - 1; $i++)
            {
                $json .= $object[$i]->toJson() . ","; 
            }
            $json .= $object[$i]->toJson() . "]";
        }
        else if(is_object($object))
        {
            $json .= $object->toJson();
        }
        return $json;
    }
    
    protected function bind()
    {
        $json = "{";
        for($i = 0; $i < func_num_args() - 1; $i++)
        {
            $json .= func_get_arg($i) . ",";
        }
        $json .= func_get_arg(func_num_args() - 1) . "}";
        return $json;
    }
    
    public function dump($fileName = "dump")
    {
        $handle = fopen($fileName . ".json", "w");
        fwrite($handle, $this->toJson());
        fclose($handle);
    }
}

?>

 

Example usage:

 

<?php

abstract class A_Polygon extends A_JsonSerializable
{   
    private static $objectCount_ = 0;
    private $id_;
    private $shapeType_;  
    
    protected $coordinates_;

    public function toJson()
    {
        return  $this->bind($this->native("id_", $this->id_), $this->element("coordinates_", $this->coordinates_));
    }   
}

?>

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.