PHP 组件化编程技巧

  但其在UI方便却有些力不从心,不仅是PHP,任何一种Web编程语言在设计UI都有类似的问题,宿主语言与HTML混和在一个文件中,大量重复的 HTML代码,毫无任何技术含量,但又非常的费时费力。于是我就希望能够对之前做过的PHP项目UI部分进行总结和归纳,将其封装为一个个小的组件(就像 Delphi中的组件一样),在界面上呈现为统一的风格,日后可以再针对这结组件编写多个CSS文件,提供“换肤”功能。

  所有的组件都继承自AbatractComponent这个类,并实现其中的toString()render()方法。AbatractComponent又有三个主要的子类,一个是容器类Continer,其又派生出PanelPopPanelGroupPanel等类,第二个是控件类Control,是所有可视控件类的父类,如ButtonLinkButton等类,第三个则是列表类List,实现有列表,名-值对的UI。

PHP 组件化编程技巧

  AbstractComponent部分代码:

  

复制代码 代码如下:

  <?php

  /**

  * Component Library

  *

  * @author Chris Mao

  * @package Component

  * @description All components must be extened from the class

  * and override the both methods of toString.

  * @copyright Copyright (c) 2009 JueRui Soft Studio

  *

  **/

  class AbstractComponent {

  /*

  * @var _style the component style's array

  *

  * @access protected

  *

  */

  protected $_style = array();

  /*

  * @var _attributes the component attribute's string

  *

  * @access protected

  *

  */

  protected $_attributes = array();

  /**

  * constructor function

  *

  * @access public

  *

  */

  public function __construct($options = null, $style = null) {

  if (!is_null($options) && (gettype($options) != "array")) {

  throw new Exception("The options must be a array!!");

  }

  if (!empty($options) && is_array($options)) {

  if (array_key_exists("style", $options)) {

  if (is_array($options["style"])) {

  $this->_style = array_merge($this->_style, $options["style"]);

  }

  unset($options["style"]);

  }

  $this->_attributes = array_merge($this->_attributes, $options);

  }

  if (!empty($style) && is_array($style)) {

  $this->_style = array_merge($this->_style, $style);

  }

  }

  /**

  * set the component attributes

  *

  * @access protected

  *

  * @param $name attribute name

  * @param $value attribute value, option

  *

  * @return AbstractComponent

  */

  protected function setAttr($name, $value) {

  if (array_key_exists($name, $this->_attributes)) {

  unset($this->_attributes[$name]);

  }

  $this->_attributes[$name] = $value;

  return $this;

  }

  /**

  * get the component attributes' value

  *

  * @access protected

  *

  * @param $name attribute name

  *

  * @return string

  */

  protected function getAttr($name) {

  return array_key_exists($name, $this->_attributes) ? $this->_attributes[$name] : null;

  }

  /**

  * set the component style

  *

  * @access protected

  *

  * @param $name style name

  * @param $value style value, option

  *

  * @return AbstractComponent

  */

  protected function setStyle($name, $value) {

  if (array_key_exists($name, $this->_style)) {

  unset($this->_style[$name]);

  }

  $this->_style[$name] = $value;

  return $this;

  }

  /**

  * get the component style's value

  *

  * @access protected

  *

  * @param $name attribute name

  *

  * @return string

  */

  protected function getStyle($name) {

  return array_key_exists($name, $this->_style) ? $this->_style[$name] : null;

  }

  /**

  * convert the component all attributes to string like name = "value"

  *

  * @access protected

  *

  * @return string

  */

  protected function attributeToString() {

  //$s = array_reduce(;

  $s = "";

  foreach($this->_attributes as $key => $value) {

  $s .= " $key=\"$value\" ";

  }

  return $s;

  }

  /**

  * convert the component style to string like style = "....."

  *

  * @access protected

  *

  * @return string

  */

  protected function styleToString() {

  if (empty($this->_style)) return "";

  $s = "";

  foreach($this->_style as $key => $value) {

  $s .= " $key: $value; ";

  }

  $s = " style=\"$s\" ";

  return $s;

  }

  /**

  * set or get the component attributes

  *

  * @access public

  *

  * @param $name attribute name

  * @param $value attribute value, option

  *

  * @return string || AbstractComponent

  */

  public function attr() {

  $name = func_get_arg(0);

  if (func_num_args() == 1) {

  return $this->getAttr($name);

  }

  else if (func_num_args() == 2) {

  $value = func_get_arg(1);

  return $this->setAttr($name, $value);

  }

  }

  /**

  * set or get the component style

  *

  * @access public

  *

  * @param $name style name

  * @param $value style value, option

  *

  * @return string || AbstractComponent

  */

  public function style() {

  $name = func_get_arg(0);

  if (func_num_args() == 1) {

  return $this->getStyle($name);

  }

  else if (func_num_args() == 2) {

  $value = func_get_arg(1);

  return $this->setStyle($name, $value);

  }

  }

  /**

  * return the HTML string

  *

  * @access public

  *

  * @return string

  **/

  public function toString() {

  thorw New AbstractException("subclass must be override this method!!");

  }

  /**

  * render the component

  *

  * @access public

  *

  * @return void

  **/

  public function render() {

  echo $this->toString();

  }

  }