PHP实例化子类

发布于 2024-12-16 14:21:33 字数 1175 浏览 2 评论 0原文

我想成为一名面向对象的编码员,所以我给自己布置了一些简单的任务。
我构建了一个显示给定目录中所有图像的类。这工作得很好,所以我将该类分成两个类,一个类读取目录中的文件名并将它们传递到一个数组中,另一个类解析该数组并显示图片。子类中的方法与父类中的方法完全相同(当然除了用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/');

I'm trying to become an object-oriented coder here, so I'm giving myself some simple tasks.
I built a class that displays all the images in a given directory. That worked fine, so I separated that class into two classes, one to read the filenames in the directory and pass them into an array, and one to parse that array and display the pictures. The method in the child class is exactly the same as it was when it was in the parent class (except of course substituting parent:: for this->).

Now it seems when I instantiate the child class and call its method, nothing happens at all.

Classes:

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/>';
        }
    }
}

Instantiation:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦开始←不甜 2024-12-23 14:21:33

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

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

/**
 * 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 (empty($this->extensions)) {
                    //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 类。

To be honest: your whole design is wrong.

  1. DisplayPics shouldn't inherit from Picfind. Honestly, either have Picfind have a display method, or have DisplayPics take the output from Picfind. Think, does the following make sense: "DisplayPics is a PicFind."? If not, it's probably wrong.
  2. Classes normally aren't verbs. A better name would be Pictures, with find and display methods. In your case, you are finding something in a directory, which leads to the next point:
  3. You should make use of the PHP DirectoryIterator class. This way, you can do whatever you'd like with the files you find. You'll have all the information about the file available to you, and it's integrated nicely with PHP.
  4. You need a separation of concerns. This is what hakre's suggestion is all about. Reducing dependencies and decoupling things is normally helpful.

/**
 * 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 (empty($this->extensions)) {
                    //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'
        );
    }
}

How to use:

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

Note that you could use the ExtensionFinder class I defined above to find files of ANY extension. That could potentially be more useful than simply finding images, but I defined a PictureFinder class for you for that specific use-case.

三岁铭 2024-12-23 14:21:33

您写道您想学习面向对象编程。那么以下呢:

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);

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

You wrote that you want to learn object oriented programming. What about the following:

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);

Keep things separated and loosely coupled. One object should be responsible for one thing, e.g. one object to obtain the list of pictures from a directory and another one for the presentation. Good luck!

噩梦成真你也成魔 2024-12-23 14:21:33

$Myclass->displayPics('./images/');
正在调用构造函数,但什么也没发生。
您的函数名称也有拼写错误。

$Myclass->displayPics('./images/');
is calling the constructor and nothing is happening.
You have a typo in your function name aswell.

太傻旳人生 2024-12-23 14:21:33

我建议改为这样的设计:

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”。

I'd suggest that design instead:

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;
    }
}

That way you only use PicDisplayer and don't care how it finds the pics. But you can still change the "PicFinder" if needed, by extending the PicFinder class and implementing a specific behavior.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文