...

View Full Version : newbie stuff



footballer27
07-28-2012, 03:41 AM
I have a couple of newbie questions that are difficult to google.

1. can I type cast instance variables
like


class foo{
public int $foo;
public string $myString;
}



2. how do magic methods work. do I still have to make them? and can I declare a return type?


public int __getFoo(){
return $this->foo;
}


thank you

Fou-Lu
07-28-2012, 06:13 AM
Nope. PHP is datatype weak, so you cannot do a return type or declaration type. All you can do is use cast types and is_*() function checks to verify the datatype. You can however use datatype enforcement as parameters with arrays or object types in methods. Properly done, you can also use signatures for any primitive type if its properly handled by the error handlers, but brings question to its overall usefulness.
No return types can be declared in any PHP method. The API lists them for completion purposes. Magic methods should only be called by the system. Constructors and destructors by the call of new and the setting to null or unsetting, sleep/wakeup on serialize/unserialize, tostring off of a printable type, clone to a clone call, get/set to non-existent members, etc. You do not have to override any of the magic methods if you choose not to. ToString is one I'd recommend overriding even in a base class just so it doesn't throw an exception if you print it. __get/__set and __call I always override to throw an exception. I do these an other things like __clone to link it to custom ICloneable through the base Object class I've written for all my objects.

footballer27
07-28-2012, 06:37 AM
Thank you
so if I have multiple protected variables I've read I only use 1 __get(){} or __set(){}

so then I have to check each variable to see if it's the right type?



public class foo{
private $_title; //string
private $_id; //int

public function __set($name, $value){
if( isset($this->$name) ){
if($name == $_title && gettype( $value) == "string")
$_title == $value;
else
throw Exception //however this is done in php

if($name == $_id && gettype( $value ) == "integer")
$_id == $value;
else
throw Exception //however this is done in php
}
}
}

is this correct?
this seems like a lot of work

Fou-Lu
07-28-2012, 07:18 AM
No, I'd write accessor's and mutators for each property that should be accessible. Its far easier to control on a per method basis than in a single set or get method.


class Object
{
public function __get($name)
{
throw new RuntimeException();
}
public function __set($name, $val)
{
throw new RuntimeException();
}
}

class foo extends Object // classes cannot have scope in PHP
{
private $_title;
private $_id;

public function getTitle()
{
return $this->_title;
}

public function getID()
{
return $this->_id;
}

public function setTitle($sTitle)
{
// rules here
$this->_title = $sTitle;
}

public function setID($id)
{
$this->_id = $id;
}
}


You also cannot use variable masking in PHP, so $this is required with any method or member within a class.

footballer27
07-28-2012, 07:44 AM
Thank you

footballer27
07-28-2012, 09:11 AM
Thank you for the previous answers.

Now I'm wondering why I can see terry's name



class Person{
protected $_id;
protected $_name;

public function __construct($name){
$this->_name = $name;
$this->_id = rand(0, 10000);
echo $this->_id;//this works
}


public function __setId($id){ $this->_id = $id; }
public function __setName($name){ $this->_name = $name; }


public function __toString(){ return "" . $_name; }

}

$terry = new Person("Terry");
echo $terry->name;//this does not work???


shouldn't this call the default __get() method?

I didn't override _get because it doesn't look like I should or need to. right? and I'll learn to throw exceptions after I figure this out

Fou-Lu
07-28-2012, 03:27 PM
No the idea is you do not want direct access to read or write any member in PHP. Since its datatype weak you will lose integrity if you do not control it individually. I suggest multiple accessors and mutators since its easier to keep track of these than it is to keep handling multiple properties in get and set. There is no default __get or __set functionality.
You have to get the name by writing a method for it. Don't start any non-magical method with __ either, as these are reserved for PHP magic methods.

DrDOS
07-28-2012, 04:46 PM
Magic methods should only be called by the system. Constructors and destructors by the call of new and the setting to null or unsetting, sleep/wakeup on serialize/unserialize, tostring off of a printable type, clone to a clone call, get/set to non-existent members, etc. You do not have to override any of the magic methods if you choose not to. ToString is one I'd recommend overriding even in a base class just so it doesn't throw an exception if you print it. __get/__set and __call I always override to throw an exception. I do these an other things like __clone to link it to custom ICloneable through the base Object class I've written for all my objects.
You obviously know about Magic and Classes. I have a hard time finding how to use them, on the web. Could you maybe put a tutorial in the snippets section, or point to a decent tutorial on the web. It would be much appreciated.

footballer27
07-28-2012, 07:18 PM
so what if I need to use the syntax



$foo->_name = "brian";
$foo->_id = "2895";


do I then need to have 1 __set() method and check for each one?



class Foo{
protected $_name;
protected $_id;

public function __set($prop, $value){
if($prop == $_name && gettype($value) == "string")
$this->_name = $value;
else if($prop == $_id && gettype($value) == "integer")
$this->_id = $value;
}
}


because it doesn't look like I can use a different __set() method for each variable and still use the syntax



$foo->_name = "brian";
$foo->_id = "2895";




class Foo{
protected $_name;
protected $_id;

public function __setName($value){
if( gettype($value) == "string" )
$this->_name = $value;
else throw new IllegalArgumentException("names must be strings");
}

public function __setId($value){
if( gettype($value) == "integer" ){
$this->_id = $value;
else
throw new IllegalArgumentException("ids must be integers");
}
}

}

Fou-Lu
07-28-2012, 07:26 PM
If your intent on dereferencing the property, then you have to override the __get and __set methods and handle each case accordingly. Only works with protected or private members of course as public ones are free and available for any external modification.

footballer27
07-28-2012, 07:41 PM
ok thank you. I would prefer to do you it your way with seperate get and set methods (I learned from java and this is the way to do it in java). but I'm afraid the choice isn't up to me.

Thanks for all your help

footballer27
07-29-2012, 12:43 AM
this has got me totally stuck. for some reason I can't use a couple of DateTime functions



$time = new DateTime();
$time->setTimestamp( 1171502725 );
return $time->format('Y-m-d H:i:s');


this is giving me an error message
Fatal error: Call to undefined method DateTime::setTimestamp() in /home/townse7/public_html/phpTest.php on line 83

I also got the same error for
DateTime::getTimestamp
when I tried to a created DateTime



$datetime = new DateTime("10/24/2011 6PM");
echo $datetime->getTimestamp();


I am totally stuck

Fou-Lu
07-29-2012, 12:45 AM
It means exactly what it says. The method setTimestamp doesn't exist in DateTime.
This indicates that your PHP version is < 5.3.0 as that is when the setTimestamp was added to the datetime class.

footballer27
07-29-2012, 12:47 AM
ahh thank you

footballer27
07-29-2012, 02:54 AM
so just to make sure I'm doing this right does this look ok? is there a more simple way?



class Person{
protected $id;//int
protected $name;//string

public function __construct($name){
$this->name = $name;
$this->id = rand(0, 10000);
}

/**
* return the current value of the given property
*/
public function __get($prop){ return $this->$prop; }

/**
* set a property
* throws an InvalidArgumentException if $value is not the correct type
*/
public function __set($prop, $value){
switch($prop){
case id:
if( gettype($value) == "integer" )
$this->id = $value;
else
throw new InvalidArgumentException("ids must be integers");
break;
case name:
if( gettype($value) == "string" )
$this->name = $value;
else
throw new InvalidArgumentException("names must be strings");
break;
}
}

/**
* returns the name of this person
*/
public function __toString(){ return "" . $this->name; }

}

Fou-Lu
07-29-2012, 04:31 PM
Yeah, although I'd use the is_* methods instead of gettype as they're quicker to evaluate.

akimmi
07-30-2012, 07:05 AM
i also newbie , i don't much know about php.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum