Link to home
Start Free TrialLog in
Avatar of rgb192
rgb192Flag for United States of America

asked on

difference between _postal_code postal_code

this is my changes to lynda.com object oriented php tutorial

demo.php
<?php

require 'class.Address.inc';

echo '<h2>Instantiating Address</h2>';
$address = new Address;

echo '<h2>Empty Address</h2>';
echo '<tt><pre>' . var_export($address, TRUE) . '</pre></tt>';

echo '<h2>Setting properties...</h2>';
$address->street_address_1 = '555 Fake Street';
$address->city_name = 'Townsville';
$address->subdivision_name = 'State';
$address->postal_code = '12345';
$address->country_name = 'United States of America';
echo '<tt><pre>' . var_export($address, TRUE) . '</pre></tt>';

echo '<h2>Displaying address...</h2>';
echo $address->display();

echo '<h2>Testing protected access.</h2>';
echo "<br>Address ID: {$address->_address_id}";
echo "<br>time created: {$address->_time_created}";

echo '<h2>Testing magic __get and __set</h2>';
unset($address->postal_code);
unset($address->_postal_code);
echo $address->display();

Open in new window



class.Address.inc
<?php

/**
 * Physical address. 
 */
class Address {
  // Street address.
  public $street_address_1;
  public $street_address_2;
  
  // Name of the City.
  public $city_name;
  
  // Name of the subdivison.
  public $subdivision_name;
  
  // Postal code.
  protected $_postal_code;
  protected $postal_code;
  
  // Name of the Country.
  public $country_name;
  
  // Primary key of an Address.
  protected $_address_id;
  
  // When the record was created and last updated.
  protected $_time_created;
  protected $_time_updated;
  
  /**
  *  Magic __get
  * @param string $name
  * @return mixed
  */
  
  function __get($name){
    echo '<h1>'.__FUNCTION__.' '.$name.'</h1>';
    //postal code lookup if unset
   // if (!$this->_postal_code){
      $this->_postal_code = '_postalcode';
      $this->postal_code = 'postalcode';
      //$this->_postal_code = $this->_postal_code_guess();
    //}
    
  //attempt to return a protected property by name.
  //$protected_property_name = '_' . $name;
  
  if ($name=='_postal_code' || $name=='postal_code'){
    $protected_property_name=$name;
  }
  
  if (property_exists($this, $protected_property_name)){
    return $this->protected_property_name;
  }
  
  //unable to access a property; trigger error.
  trigger_error('Undefined property via __get: ' . $name);
  return NULL;
    
  }
  /**
  * magic __set
  * 
  * @param string $name
  * @param mixed $value
  */
   function __set($name,$value){
     //Allow anything to set the postal code
     if ('postal_code' == $name || '_postal_code' == $name){
       $this->$name = $value;
       return;
     }
     
     //unable to access property; trigger error.
     trigger_error('Undefined or unallowed property via __set(): '.$name);
   }
  
  
  /**
  * guess the postal code given the subdivision and city name
  * @todo replace with a database lookup
  * @return string
  * 
  */
  protected function _postal_code_guess(){
    return 'LOOKUP';
  }
  
  /**
   * Display an address in HTML.
   * @return string 
   */
  function display() {
    $output = '';
    
    // Street address.
    $output .= $this->street_address_1;
    if ($this->street_address_2) {
      $output .= '<br/>' . $this->street_address_2;
    }
    
    // City, Subdivision Postal.
    $output .= '<br/>';
    $output .= $this->city_name . ', ' . $this->subdivision_name;
    $output .= ' _pc:' . $this->_postal_code. ' pc:'.$this->postal_code;
    
    // Country.
    $output .= '<br/>';
    $output .= $this->country_name;
    
    return $output;
  }
}

Open in new window



output
Instantiating Address
Empty Address
Address::__set_state(array(
   'street_address_1' => NULL,
   'street_address_2' => NULL,
   'city_name' => NULL,
   'subdivision_name' => NULL,
   '_postal_code' => NULL,
   'postal_code' => NULL,
   'country_name' => NULL,
   '_address_id' => NULL,
   '_time_created' => NULL,
   '_time_updated' => NULL,
))
Setting properties...
Address::__set_state(array(
   'street_address_1' => '555 Fake Street',
   'street_address_2' => NULL,
   'city_name' => 'Townsville',
   'subdivision_name' => 'State',
   '_postal_code' => NULL,
   'postal_code' => '12345',
   'country_name' => 'United States of America',
   '_address_id' => NULL,
   '_time_created' => NULL,
   '_time_updated' => NULL,
))
Displaying address...
555 Fake Street
Townsville, State _pc: pc:12345
United States of America
Testing protected access.
__get _address_id

Notice: Undefined property via __get: _address_id in C:\wamp\www\Ex_Files_oophp-edit2\03_02\class.Address.inc on line 58

Address ID: 
__get _time_created

Notice: Undefined property via __get: _time_created in C:\wamp\www\Ex_Files_oophp-edit2\03_02\class.Address.inc on line 58

time created: 
Testing magic __get and __set

Fatal error: Cannot access protected property Address::$postal_code in C:\wamp\www\Ex_Files_oophp-edit2\03_02\demo.php on line 27

Open in new window



I avoid the fatal error by commenting
//unset($address->postal_code);
//unset($address->_postal_code);


I made changes to the code because I do not understand the difference between
_postal_code
postal_code
SOLUTION
Avatar of Beverley Portlock
Beverley Portlock
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thinking a bit further about this I feel I need to clarify something. The __get and __set magic methods are called when fetching or assigning a value to a protected/private property.

unset neither assigns or fetches a value so neither __get not __set will be called. unset destroys a variable.
Sadly, this looks like one of those old code samples that is simply internet litter.  It has a distinct code smell (the lines that are commented out but left in the class do not make any sense) and it looks very hypothetical at best, and confusing.  Agree with BPortlock that there is little sense to having two postal codes.  Even the direct mail programmers don't do something like that!

Old and bad programming examples do not come with expiration dates, so they lie around forever waiting for someone to turn them up and learn bad practices from them.  In particular, the PHP4 object model was one of the worst pieces of programming ever devised.  So when you see programming that uses leading underscores on variable names, run away.

A much better learning resource than Lynda.com is this excellent book.  Get the latest version, and when a new version comes out, get the new version!
http://www.amazon.com/PHP-MySQL-Web-Development-Edition/dp/0321833899

Another better resource is CodeAcademy.  Its examples seem to be newer and better vetted.
Avatar of rgb192

ASKER

The lynda.com example
had
only 1 of the 2:
_postal_code
or
postal_code

but seemed to use both

so I copy pasted both _postal_code and postal_code
every time that one was called because I did not understand.

>>Another better resource is CodeAcademy.  Its examples seem to be newer and better vetted.
Is code academy a 22 year old

I prefer experienced experts.
I prefer experienced experts.
I think we all do.  I had dinner with a 23-year old this week who started programming in PHP at age 16.  That makes for a lot of experience!

Interesting thing about unset()... It can also destroy a "reference" without destroying the variable.  So be careful if you're using an iterator that creates and unsets references.  The potential for a memory leak is obvious.
http://www.laprbass.com/RAY_unset_oop.php

<?php // RAY_unset_oop.php
ini_set('display_errors', TRUE);
error_reporting(E_ALL);

// DEMONSTRATE THE EFFECT OF UNSET WHEN MORE THAN ONE REFERENCE EXISTS

// CREATE AN OBJECT AND LOAD SOME DATA
$a = new StdClass;
$a->inner = 'A';

// CREATE A NEW REFERENCE TO THE OBJECT
$b = $a;

// SEE WHAT HAPPENS
unset($a);
var_dump($b);

Open in new window

Avatar of rgb192

ASKER

<?php // RAY_unset_oop.php
ini_set('display_errors', TRUE);
error_reporting(E_ALL);

// DEMONSTRATE THE EFFECT OF UNSET WHEN MORE THAN ONE REFERENCE EXISTS

// CREATE AN OBJECT AND LOAD SOME DATA
$a = new StdClass;
$a->inner = 'A';

// CREATE A NEW REFERENCE TO THE OBJECT
$b = $a;
echo '<br>before unset: ';
var_dump($b);
// SEE WHAT HAPPENS
unset($a);
echo '<br>after unset: ';
var_dump($b);

Open in new window


I do not understand because $b is the same before and after the unset of $a
but $a disappears.

before unset: object(stdClass)#1 (1) { ["inner"]=> string(1) "A" }
after unset: object(stdClass)#1 (1) { ["inner"]=> string(1) "A" }
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of rgb192

ASKER

So protected and variables and references tutorial

thanks both