Magic Methods not working

Magic Methods not working

am 27.01.2010 04:04:38 von Paul M Foster

I have a class which instantiates other classes, and has a magic method
like this:

function _get($classname)
{
return $this->instantiate($classname);
}

Obviously, the class also has an instantiate method which does what it
says.

Here's the problem: When I call the instantiate method, it works fine,
like this:

$db = $sc->instantiate('database');

But when I do the following, it *doesn't* work:

$db = $sc->database;

In fact it does not call the instantiate() method; I've placed a print
statement in the instantiate() method which fires at then end of the
routine. That statement doesn't fire with the above code.

The docs on magic methods are pretty slim, so I'm not sure what it is
I'm missing. Can someone enlighten me?

Paul


--
Paul M. Foster

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: Magic Methods not working

am 27.01.2010 04:19:34 von Eric Lee

--0016e657b50e1ace47047e1cdfa3
Content-Type: text/plain; charset=UTF-8

On Wed, Jan 27, 2010 at 11:04 AM, Paul M Foster wrote:

> I have a class which instantiates other classes, and has a magic method
> like this:
>
> function _get($classname)
> {
> return $this->instantiate($classname);
> }
>
> Obviously, the class also has an instantiate method which does what it
> says.
>
> Here's the problem: When I call the instantiate method, it works fine,
> like this:
>
> $db = $sc->instantiate('database');
>
> But when I do the following, it *doesn't* work:
>
> $db = $sc->database;
>
> In fact it does not call the instantiate() method; I've placed a print
> statement in the instantiate() method which fires at then end of the
> routine. That statement doesn't fire with the above code.
>
> The docs on magic methods are pretty slim, so I'm not sure what it is
> I'm missing. Can someone enlighten me?
>
> Paul
>
>
Paul,

I seem that you should missed the required underscore " _ "
It should the __get() but not _get().
Shall this help ?

And here is a quick test !!

[ [ [
class test
{
public $varname = 1000;

public function __get($name)
{
return $this->init($name);
}

public function init($name)
{
return new test();
}
}

$t = new test();
$db = $t->database;
if (is_object($db))
{
echo $db->varname;
}

] ] ]


Regards,
Eric,


--
> Paul M. Foster
>
> --
> PHP General Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>

--0016e657b50e1ace47047e1cdfa3--

RE: Magic Methods not working

am 27.01.2010 04:21:34 von Daevid Vincent

> -----Original Message-----
> From: Paul M Foster [mailto:paulf@quillandmouse.com]
> Sent: Tuesday, January 26, 2010 7:05 PM
> To: php-general@lists.php.net
> Subject: [PHP] Magic Methods not working
>
> I have a class which instantiates other classes, and has a
> magic method
> like this:
>
> function _get($classname)
> {
> return $this->instantiate($classname);
> }
>
> Obviously, the class also has an instantiate method which does what it
> says.
>
> Here's the problem: When I call the instantiate method, it works fine,
> like this:
>
> $db = $sc->instantiate('database');
>
> But when I do the following, it *doesn't* work:
>
> $db = $sc->database;
>
> In fact it does not call the instantiate() method; I've placed a print
> statement in the instantiate() method which fires at then end of the
> routine. That statement doesn't fire with the above code.
>
> The docs on magic methods are pretty slim, so I'm not sure what it is
> I'm missing. Can someone enlighten me?
>
> Paul

http://us2.php.net/manual/en/language.oop5.magic.php

There are TWO underscores needed, not one.

__get()

Also, just to save you some time/grief, you might consider using my awesome
routines:

Put these in your base.class.php and extend it for all other classes.
Magic.

/**
* Provides generic getters and setters
*
* @access public
* @param string $method The method name.
* @param array $arguments The arguments passed to the method.
* @return mixed
* @author Daevid Vincent [daevid@daevid.com]
* @date 02/02/09
* @see __get(), __set()
*/
public function __call( $method, $arguments )
{
$prefix = strtolower( substr( $method, 0, 3 ) );
$property = strtolower( substr( $method, 4 ) );

if ( empty($prefix) || empty($property) ) return;
//exit("__call($method) :: prefix='$prefix' and
property='$property'");

if ( 'get' == $prefix )
{
if ( property_exists($this, $property) )
return $this->$property;
else
return $this->__get($property);
}
elseif ( 'set' == $prefix )
{
if ( property_exists($this, $property) )
return $this->$property = $arguments[0];
else
return $this->__set($property, $arguments[0]);
}

// Technically we should never get to this point as most calls are
get_() or set_()
echo "

Attempted to
'".$prefix."->".$method."()' in class
'".$this->get_class_name()."'.

\n";
backtrace();
}

/**
* magic function to handle any accessing of undefined variables.
* Since PHP is "lax" this will help prevent stupid mistakes.
*
* @access public
* @return void
* @param mixed $property name of the variable
* @author Daevid Vincent [daevid@daevid.com]
* @date 05/14/09
* @see __set(), __call()
*/
public function __get($property)
{
if ($_SESSION['DEVELOPMENT'] && !$_SESSION['mobile'])
{
echo "

Attempted to __get()
non-existant property/variable '".$property."' in class
'".$this->get_class_name()."'.

\n";
$this->suggest_alternative($property);
backtrace();
exit;
}
else exit("__get($property) NO SUCH PROPERTY IN
".$this->get_class_name().' CLASS');

//Throw new BadProperty($this, 'get', $property);
}

/**
* magic function to handle any setting of undefined variables.
* Since PHP is "lax" this will help prevent stupid mistakes.
*
* @access public
* @return void
* @param mixed $property name of the variable
* @param mixed $val value of the variable
* @author Daevid Vincent [daevid@daevid.com]
* @date 05/14/09
* @see __get(), __call()
*/
public function __set($property, $val)
{
if ($_SESSION['DEVELOPMENT'] && !$_SESSION['mobile'])
{
echo "

Attempted to __set()
non-existant property/variable '".$property."' to '".$val."' in class
'".$this->get_class_name()."'.

\n";
$this->suggest_alternative($property);
backtrace();
exit;
}
else exit("__set($property) NO SUCH PROPERTY IN
".$this->get_class_name().' CLASS');

//Throw new BadProperty($this, 'set', $property);
}

/**
* Suggests alternative properties should a __get() or __set() fail
*
* @param string $property
* @return string
* @author Daevid Vincent [daevid@daevid.com]
* @date 05/19/09
* @see __get(), __set(), __call()
*/
public function suggest_alternative($property)
{
$parts = explode('_',$property);
foreach($parts as $i => $p) if ( in_array($p,
array('_','id','get','set')) ) unset($parts[$i]);

echo 'checking for '.implode(' or ',$parts)." and suggesting
the following:
\n";

foreach($this as $key => $value)
foreach($parts as $p)
if (stripos($key, $p) !== false)
{
if ($property == 'get_'.$p || $property ==
'set_'.$p)
$possibilities[] =
'

  • '.$key."() note the parenthesis
  • ";
    else
    $possibilities[] =
    '
  • '.$key."
  • ";
    }

    echo "\n";

    //[dv] unfortunately there doesn't seem to be a way to know if
    someone called this as a method () or directly :(
    //if ( strpos($property, '()') === false )
    if (count($parts) == 1 && $property == 'get_'.$parts[0] ||
    $property == 'set_'.$parts[0])
    echo 'Perhaps you forgot the parenthesis at the end of the
    method call, and meant this instead: '.$property.'()';
    }


    --
    PHP General Mailing List (http://www.php.net/)
    To unsubscribe, visit: http://www.php.net/unsub.php

    Re: Magic Methods not working

    am 27.01.2010 04:31:11 von Paul M Foster

    On Wed, Jan 27, 2010 at 11:19:34AM +0800, Eric Lee wrote:

    >
    >
    > On Wed, Jan 27, 2010 at 11:04 AM, Paul M Foster
    > wrote:
    >
    > I have a class which instantiates other classes, and has a magic method
    > like this:
    >
    > function _get($classname)
    > {
    >        return $this->instantiate($classname);
    > }
    >
    > Obviously, the class also has an instantiate method which does what it
    > says.
    >
    > Here's the problem: When I call the instantiate method, it works fine,
    > like this:
    >
    > $db = $sc->instantiate('database');
    >
    > But when I do the following, it *doesn't* work:
    >
    > $db = $sc->database;
    >
    > In fact it does not call the instantiate() method; I've placed a print
    > statement in the instantiate() method which fires at then end of the
    > routine. That statement doesn't fire with the above code.
    >
    > The docs on magic methods are pretty slim, so I'm not sure what it is
    > I'm missing. Can someone enlighten me?
    >
    > Paul
    >
    >
    >
    > Paul,
    >
    > I seem that you should missed the required underscore " _  "
    > It should the __get() but not _get().
    > Shall this help ?

    Great Caesar's Ghost! You're right! Thanks.

    Paul

    --
    Paul M. Foster

    --
    PHP General Mailing List (http://www.php.net/)
    To unsubscribe, visit: http://www.php.net/unsub.php

    Re: Magic Methods not working

    am 27.01.2010 04:45:35 von Paul M Foster

    On Tue, Jan 26, 2010 at 07:21:34PM -0800, Daevid Vincent wrote:

    > > -----Original Message-----
    > > From: Paul M Foster [mailto:paulf@quillandmouse.com]
    > > Sent: Tuesday, January 26, 2010 7:05 PM
    > > To: php-general@lists.php.net
    > > Subject: [PHP] Magic Methods not working
    > >
    > > I have a class which instantiates other classes, and has a
    > > magic method
    > > like this:
    > >
    > > function _get($classname)
    > > {
    > > return $this->instantiate($classname);
    > > }
    > >
    > > Obviously, the class also has an instantiate method which does what it
    > > says.
    > >
    > > Here's the problem: When I call the instantiate method, it works fine,
    > > like this:
    > >
    > > $db = $sc->instantiate('database');
    > >
    > > But when I do the following, it *doesn't* work:
    > >
    > > $db = $sc->database;
    > >
    > > In fact it does not call the instantiate() method; I've placed a print
    > > statement in the instantiate() method which fires at then end of the
    > > routine. That statement doesn't fire with the above code.
    > >
    > > The docs on magic methods are pretty slim, so I'm not sure what it is
    > > I'm missing. Can someone enlighten me?
    > >
    > > Paul
    >
    > http://us2.php.net/manual/en/language.oop5.magic.php
    >
    > There are TWO underscores needed, not one.
    >
    > __get()
    >
    > Also, just to save you some time/grief, you might consider using my awesome
    > routines:
    >
    > Put these in your base.class.php and extend it for all other classes.
    > Magic.

    Oh no. I can't use those. The braces are in all the wrong places! (All
    praise be to K&R...) ;-}

    Paul

    --
    Paul M. Foster

    --
    PHP General Mailing List (http://www.php.net/)
    To unsubscribe, visit: http://www.php.net/unsub.php