something advanced in the code preventing me from adding properties to the object

line 43: I think $address->numbersAndLetters should be in the $address object
line 43: I think $address->numbersAndLetters should be in the $address object
<?php
class Address {
    private $number;
    private $street;
    //public $streetaddress='no need for methods';
    public $maybestreet= 'this is it';

    function __construct( $maybenumber, $maybestreet=null ) {
        if ( is_null( $this->maybestreet ) ) {
            $this->streetaddress = $maybenumber;
        } else {
            $this->number = $maybenumber;
            $this->street = $maybestreet;
        }
    }

    function __set( $property, $value ) {
        if ( $property === "streetaddress" ) {
            if ( preg_match( "/^(\d+.*?)[\s,]+(.+)$/", $value, $matches ) ) {
                $this->number = $matches[1]; 
                $this->street = $matches[2]; 
            } else {
                throw new Exception("unable to parse street address: '{$value}'");
            }
        }    
    }

    function __get( $property ) {
        if ( $property === "streetaddress" ) {
            return $this->number." ".$this->street;
        }
    }
}

$address = new Address( "441b Bakers Street" );
print_r( $address );

print "street address: {$address->streetaddress}\n";
$address = new Address( 15, "Albert Mews" );
print "street address: {$address->streetaddress}\n";
$address->streetaddress = "34, West 24th Avenue";
print "street address: {$address->streetaddress}\n";
$address->numbersAndLetters='31 red rd';
$address->streetaddress = "failme";

?>

Open in new window

LVL 1
rgb192Asked:
Who is Participating?
 
Ray PaseurConnect With a Mentor Commented:
From the man page:
PHP's interpretation of "overloading" is different than most object oriented languages. Overloading traditionally provides the ability to have multiple methods with the same name but different quantities and types of arguments.
It might be more semantically correct to say this is injection, since the term carries a negative connotation.  If you inject properties into an object without defining the properties in the class, you've created a stumbling block for yourself.  Consider what would happen if two programmers chose the same variable name.

This code snippet shows a bit of how PHP handles or mishandles this sort of thing.  With the __set() magic method, even protected variables become mutable.  If the __set() method did not raise a message, you would have no way of knowing at run time that something in the code had damaged a protected class property!  Without __set() you would get a fatal error if a script tried to modify a protected variable.  You can experiment with this script to see what PHP is doing.  Try commenting out the __set() method and running the script to see the differences.

<?php // oop_overload.php
error_reporting(E_ALL);

// INJECTION OF PROPERTIES INTO PHP OBJECTS

class SafeData
{
    // AN ATTEMPT TO MODIFY THIS FROM OUTSIDE THE OBJECT WILL CREATE A NOTICE, NOT AN ERROR
    protected $str;

    // THIS WILL BE CALLED BY ANY ATTEMPT TO SET AN UNDEFINED PROPERTY
    public function __set($name, $value)
    {
        $msg = "Attempt to inject (PHP <a href='http://www.php.net/manual/en/language.oop5.overloading.php#object.set'>overload</a>) property <b>$name</b> to $value in ";
        trigger_error($msg . __CLASS__, E_USER_NOTICE);
    }

    public function __construct($str)
    {
        $this->str = $str;
    }
}

$x = new safedata('Hello');
$x->foo = 'thud';
$x->str = 'World';

Open in new window

0
 
Ray PaseurCommented:
Properties of an object have three characteristics: public, protected and private.  Public properties (the default characteristic) can be set and accessed from any scope or namespace.  Protected properties can be accessed from within the class and any child that extends the class.  Private properties are only available to the class itself, and not to any extension.
0
 
rgb192Author Commented:
I think
line43
$address->numbersAndLetters='31 red rd';
is public because there is no protected/private restrictions from class Address
0
 
Dan CraciunConnect With a Mentor IT ConsultantCommented:
Since "numbersAndLetters" is not a declared property of the class "address", this line
$address->numbersAndLetters='31 red rd';
overloads the property. Put otherwise, it adds a property on-the-fly, but that is limited to that object/instance, it's not really added to the class.

See here: http://www.php.net/manual/en/language.oop5.overloading.php

HTH,
Dan
0
 
rgb192Author Commented:
I like the example commenting out the set method.
also
$address->numbersAndLetters='31 red rd';
overloads the property. Put otherwise, it adds a property on-the-fly

thanks both.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.