Ver Mensaje Individual
  #1 (permalink)  
Antiguo 02/12/2010, 18:17
glisandro
 
Fecha de Ingreso: diciembre-2010
Ubicación: Argentina
Mensajes: 5
Antigüedad: 14 años
Puntos: 0
Duda con __get() y __set()

Hola

Estoy mirando un poco como trabaja una aplicación ([URL="http://www.dasprids.de/blog/2010/10/20/modern-application-design-part-2"]Modern Application[/URL]) para entender un poco más algunas técnicas POO y me surgió una duda con respecto a la implementación de los métodos mágicos que comenté antes.

La base es esta:

Código PHP:
Ver original
  1. <?php
  2. /**
  3.  * Abstract domain model
  4.  */
  5. abstract class App_Model_ModelAbstract
  6. {
  7.     /**
  8.      * Allowed fields in this entity
  9.      *
  10.      * @var array
  11.      */
  12.     protected $_fields = array();
  13.    
  14.     /**
  15.      * List of field values
  16.      *
  17.      * @var array
  18.      */
  19.     protected $_values = array();
  20.    
  21.     /**
  22.      * Create an new instance of this domain model
  23.      *
  24.      * @param array $values
  25.      */
  26.     public function __construct(array $values)
  27.     {
  28.         foreach ($values as $name => $value) {
  29.             $this->$name = $value;
  30.         }
  31.     }
  32.    
  33.     /**
  34.      * Set a field
  35.      *
  36.      * @param  string $name
  37.      * @param  mixed  $value
  38.      * @throws App_Model_OutOfBoundsException When field does not exist
  39.      * @return void
  40.      */
  41.     public function __set($name, $value)
  42.     {      
  43.         $method = '_set' . ucfirst($name);
  44.        
  45.         if (method_exists($this, $method)) {
  46.             $this->{$method}($value);
  47.         } else if (in_array($name, $this->_fields)) {
  48.             $this->_values[$name] = $value;
  49.         } else {
  50.             throw new App_Model_OutOfBoundsException('Field with name ' . $name . ' does not exist');
  51.         }
  52.     }
  53.    
  54.     /**
  55.      * Get a field
  56.      *
  57.      * @param  string $name
  58.      * @throws App_Model_OutOfBoundsException When field does not exist
  59.      * @return mixed
  60.      */
  61.     public function __get($name)
  62.     {
  63.         $method = '_get' . ucfirst($name);
  64.        
  65.         if (method_exists($this, $method)) {
  66.             return $this->{$method}();
  67.         } else if (in_array($name, $this->_fields)) {
  68.             if (!array_key_exists($name, $this->_values)) {
  69.                 throw new App_Model_RuntimeException('Trying to accessing field ' . $name . ' which value was not set yet');
  70.             }
  71.  
  72.             return $this->_values[$name];
  73.         } else {
  74.             throw new App_Model_OutOfBoundsException('Field with name ' . $name . ' does not exist');
  75.         }
  76.     }
  77. }
http://site.svn.dasprids.de/trunk/application/library/App/Model/ModelAbstract.php

El constructor es el encargado de llamar a cada método a partir de lo que reciva en $values, pero va a llamar a todos los metodos ya sean set o get, entonces es solamente una diferencia semantica ? el objeto podría funcionar solo con get por ejemplo ?

Acá está una implementaciíon de la clase anterior
Código PHP:
Ver original
  1. <?php
  2. /**
  3.  * Article domain model
  4.  */
  5. class Blog_Model_Article extends App_Model_ModelAbstract
  6. {
  7.     /**
  8.      * @see App_Model_ModelAbstract::$_fields
  9.      * @var array
  10.      */
  11.     protected $_fields = array(
  12.         'id',
  13.         'title',
  14.         'content',
  15.         'slug',
  16.         'datetime',
  17.         'comments',
  18.         'tags',
  19.         'permanentUrl',
  20.         'absolutePermanentUrl'
  21.     );
  22.  
  23.     /**
  24.      * Set the title
  25.      *
  26.      * @param  string $title
  27.      * @return void
  28.      */
  29.     protected function _setTitle($title)
  30.     {
  31.         $this->_values['title'] = $title;
  32.         $this->_setSlug($title);
  33.     }
  34.        
  35.     /**
  36.      * Set the slug, will automatically be normalized
  37.      *
  38.      * @param  string $slug
  39.      * @return void
  40.      */
  41.     protected function _setSlug($slug)
  42.     {
  43.         $slug = iconv('utf-8', 'ascii//translit', $slug);
  44.         $slug = strtolower($slug);
  45.         $slug = preg_replace('#[^a-z0-9\-_]#', '-', $slug);
  46.         $slug = preg_replace('#-{2,}#', '-', $slug);
  47.        
  48.         $this->_values['slug'] = $slug;
  49.     }
  50.    
  51.     /**
  52.      * Get the perment URL
  53.      *
  54.      * @return string
  55.      */
  56.     protected function _getPermanentUrl()
  57.     {
  58.         if (!isset($this->_values['permanentUrl'])) {
  59.             $urlHelper = new Zend_View_Helper_Url();
  60.    
  61.             $this->_values['permanentUrl'] = $urlHelper->url(array(
  62.                 'year'  => $this->datetime->get('yyyy'),
  63.                 'month' => $this->datetime->get('MM'),
  64.                 'day'   => $this->datetime->get('dd'),
  65.                 'slug'  => $this->slug
  66.             ), 'blog-article');
  67.         }
  68.  
  69.         return $this->_values['permanentUrl'];
  70.     }
  71.  
  72.     /**
  73.      * Get the absolute permanent URL
  74.      *
  75.      * @return string
  76.      */
  77.     protected function _getAbsolutePermanentUrl()
  78.     {
  79.         $front   = Zend_Controller_Front::getInstance();
  80.         $request = $front->getRequest();
  81.         $baseUri = $request->getScheme() . '://'
  82.                  . $request->getHttpHost();
  83.  
  84.         return $baseUri . $this->permanentUrl;
  85.     }
  86. }
http://site.svn.dasprids.de/trunk/application/modules/blog/models/Article.php