如何让Factory Class在PHP中创建对象实例?

时间:2013-11-15 18:45:26

标签: php xml factory-pattern

我有一个包含许多成员条目的XML文件,格式如下:

<staff>
    <member>
        <name></name>
        <image></image>
        <title></title>
        <email></email>
        <phone></phone>
        <location></location>
        <info></info>
        <webTitle></webTitle>
        <webURL></webURL>
    </member>
</staff>

设置

我创建了2个PHP类DisplayStaffEmployee

  • Employee创建一个Employee对象,上面的XML中列出了私有属性。
  • DisplayStaff是一个工厂类。它加载上面的XML文件,遍历它,为XML中的每个Employee元素创建一个<member>实例。它将Employee对象存储在数组$Employees[]

在我想输出员工信息的页面上,我希望能够像这样引用它。

$Employees = new DisplayStaff();
$John = Employees['John'];
echo "Hello, my name is $John->name";

<?php
 class DisplayStaff
 {
    private var $staffList;
    private var $placeholderImg;
    private var $Employees; 

    public function __construct() {
        $staffList      = simplexml_load_file("../data/staff.xml");
        $placeholderImg = $staffList->placeholderImg;
        foreach ( $staffList->member as $member ) {
            $employee = formatEmployeeObj( $member );
            array_push( $Employees, $employee );
        }
        return $Employees;
     }

     private function formatEmployeeObj( $memberXML ) {
         $Employee = new Employee();

         $Employee->set( $name,      $memberXML->name );
         $Employee->set( $image,     $memberXML->image );
         $Employee->set( $title,     $memberXML->title );
         $Employee->set( $email,     $memberXML->email );
         $Employee->set( $phone,     $memberXML->phone );
         $Employee->set( $location,  $memberXML->location );
         $Employee->set( $info,      $memberXML->info );
         $Employee->set( $webTitle,  $memberXML->webTitle );
         $Employee->set( $webURL,    $memberXML->webURL );

         return $Employee;
     }
}
?>

<?php
class Employee
{

     private var $name     = "";
     private var $image    = "";
     private var $title    = "";
     private var $email    = "";
     private var $phone    = "";
     private var $location = "";
     private var $info     = "";
     private var $webTitle = "";
     private var $webURL   = "";

        public function get($propertyName) {
        if( property_exists($this, $propertyName) ) {
            return $this->$propertyName;
        }
            else{
                return null;
           }
    }

    public function set($propertyName, $propertyValue) {
        if( property_exists($this, $propertyName) ){
            $this->$propertyName = $propertyValue;
        }
    }
}

?>

问题

我似乎无法让这个工作。我刚开始上课。我需要改变什么才能让我的课程表达我对他们的期望?

感谢您提前获取任何帮助。

2 个答案:

答案 0 :(得分:1)

  1. 从每个类字段中删除var。这对于public是多余的,并且从PHP5开始也被弃用。 More on this

  2. 构造函数不应返回任何内容。它会自动返回有问题的对象。但请注意,无法访问任何DisplayStaff字段,因为它们都是私有的,没有访问器功能。你可以像Employee中那样使用通用访问器,但是有理由不简单地使用public字段吗?

  3. 每次在类声明中引用对象的方法或属性时,都需要使用$this关键字,即

    public function __construct() {
      $this->staffList  = simplexml_load_file("staff.xml");
      $this->placeholderImg = $this->staffList->placeholderImg
      foreach ( $this->staffList->member as $member ) {
        $employee = $this->formatEmployeeObj( $member );
        array_push( $this->Employees, $employee );
      }
    //no need for a return
    }
    
  4. 您的Employee属性访问器方法(Employee->get())将字符串作为第一个参数,即'name'$name是未定义的变量,因此无效。

  5. 您需要初始化Employees数组,然后才能推送它。

    private $Employees = array();
    

答案 1 :(得分:0)

请注意,为简洁起见,我省略了许多Employee属性和方法。

class StaffFactory
{
    public $employees = array();

    public function __construct($xml)
    {
        $xml = simplexml_load_file($xml);
        foreach ( $xml->member as $member ) {
            $this->employees[(string) $member->name] = new Employee((array) $member);
        }
    }

    public function getEmployee($name)
    {
        if ( isset($this->employees[$name]) ) {
            return $this->employees[$name];
        }
        return false;
    }

}
class Employee {

    public $email;

    public $name;

    public $title;

    public function __construct(array $employee)
    {
        foreach ( $employee as $k => $v ) {
            if ( property_exists($this, $k) ) {
                $this->{$k} = $v;   
            }
        }
        return $this;
    }

}
$staffFactory = new StaffFactory('staff.xml');
$john = $staffFactory->getEmployee('John');

if ( $john ) {
    echo '<pre>';
    print_r($staffFactory);
    print_r($john);
    print_r($john->email);
    echo '</pre>';
}