PHP实例化子类

时间:2011-11-17 19:00:51

标签: php class parent instantiation

我想在这里成为一个面向对象的编码器,所以我给自己做了一些简单的任务 我构建了一个显示给定目录中所有图像的类。这很好,所以我将该类分成两个类,一个用于读取目录中的文件名并将它们传递给一个数组,另一个用于解析该数组并显示图片。子类中的方法与父类中的方法完全相同(当然,将parent ::替换为this->除外)。

现在看来,当我实例化子类并调用它的方法时,根本没有任何事情发生。

类:

class Picfind
{
   public function findPics($dir){
       $files = array();
       $i=0;
       $handle = opendir($dir);
       while (false !== ($file = readdir($handle))){
           $extension = strtolower(substr(strrchr($file, '.'), 1));
           if($extension == 'jpg' || $extension == 'gif' || $extension == 'png'){
                // now use $file as you like
                $i++;
                $files['file' . $i] = $file;
           }
       }
       return $files;
    }
}

class DisplayPics extends Picfind
{

    function diplayPics($dir) 
    {
        echo 'displayPics method called';

        foreach(parent::findPics($dir) as $key => $val) {
            echo '<img src="' . $dir . $val . '" img><br/>';
        }
    }
}

实例化

include("class.picFind.php");
$Myclass = new DisplayPics();
$Myclass->displayPics('./images/');

4 个答案:

答案 0 :(得分:5)

说实话:你的整个设计都是错误的。

  1. DisplayPics不应该继承Picfind老实说,要么Picfind有显示方法,要么DisplayPics获取输出来自Picfind。想一想,以下是否有意义:“DisplayPics是一个PicFind。”?如果没有,那可能就错了。
  2. 类通常不是动词。更好的名称是Pictures,使用finddisplay方法。在您的情况下,您正在目录中找到某些内容,这将导致下一点:
  3. 您应该使用PHP DirectoryIterator类。这样,您可以使用您找到的文件执行任何操作。您将获得有关该文件的所有信息,并且它与PHP很好地集成。
  4. 你需要分离关注点。这就是hakre的建议。减少依赖关系和解耦事物通常很有帮助。

  5. /**
     * ExtensionFinder will find all the files in a directory that have the given
     * extensions.
     */
    class ExtensionFinder extends DirectoryIterator {
    
        protected $extensions =  array();
    
        public function __contruct($directory) {
            parent::__construct($directory);
    
        }
    
        /**
         * Sets the extensions for the iterator. 
         * @param array $extensions The extensions you want to get (without the dot).
         */
        public function extensions(array $extensions) {
            $this->extensions = $extensions;
        }
    
        /**
         * Determines if this resource is valid.  If you return false from this 
         * function, the iterator will stop.  
         * @return boolean Returns true if the value is a file with proper extension.
         */
        public function valid() {
            if (parent::valid()) {
                $current = parent::current();
    
                if ($current->isFile()) {
                    //if the extensions array is empty or null, we simply accept it.
                    if (isset($this->extensions) && count($this->extensions)>0) {
                        //otherwise filter it
                        if (in_array($current->getExtension(), $this->extensions)) {
                             return true;
                        } else {
                            parent::next();
                            return $this->valid();
                        }
                    } else {
                        return true;
                    }
                } else {
                    parent::next();
                    return $this->valid();
                }
            } else {
                return false;
            }
    
        }
    }
    
    class PictureFinder extends ExtensionFinder {
        public function __construct($directory) {
            parent::__construct($directory);
    
            $this->extensions = array (
                'jpg',
                'gif',
                'png'
            );
        }
    }
    

    使用方法:

    $iterator = new PictureFinder('img/');
    foreach($iterator as $file) {
        //do whatever you want with the picture here.
        echo $file->getPathname()."\n";
    }    
    

    请注意,您可以使用我在上面定义的ExtensionFinder类来查找任何扩展名的文件。这可能比简单地查找图像更有用,但我为您定义了一个PictureFinder类用于该特定用例。

答案 1 :(得分:2)

你写道,你想要学习面向对象的编程。以下是什么:

class PicFinder
{
   /**
    * @return array
    */
   public function inDirectory($directory)
   {
       return // array of files
   }
}

class PicPresentation
{
    public function present(array $pictures)
    {
        // your presentation code
    }
}


$path = '/your/path';
$datasource = new PicFinder();
$presentation = new PicPresentation();
$pictures = $datasource->inDirectory($path);
$presentation->present($pictures);

保持分离和松散耦合。一个对象应该对一件事负责,例如一个对象从目录中获取图片列表,另一个对象用于演示。祝你好运!

答案 2 :(得分:0)

$ Myclass-&GT; displayPics( './图像/'); 正在调用构造函数,没有任何事情发生。 您的函数名称中也有拼写错误。

答案 3 :(得分:0)

我建议改为设计:

class PicFinder
{
    public function findPics($dir){
       ...
    }
}

class PicDisplayer
{
    protected $picFinder;

    public function __construct() {
        // Default pic finder
        $this->setPicFinder(new PicFinder());
    }

    public function diplayPics($dir)  {
        echo 'displayPics method called';

        foreach($this->getPicFinder()->findPics($dir) as $key => $val) {
            echo '<img src="' . $dir . $val . '" img><br/>';
        }
    }

    protected function setPicFinder(PicFinder $picFinder) {
        $this->picFinder = $picFinder;
    }
    protected function getPicFinder() {
        return $this->picFinder;
    }
}

这样你只使用PicDisplayer而不关心它是如何找到照片的。但是,如果需要,您仍然可以通过扩展PicFinder类并实现特定行为来更改“PicFinder”。