向 Select 元素添加值选项

Adding Value Options to Select Element

我正在尝试为具有 Zend Framework 2 形式 class 的 select 对象设置多个值,但它只传递一个值。这是我的代码:

public function addphotosAction()
{
    $identity = $this->identity();
    $files = array();
    $album_name = array();

    foreach (glob(getcwd() . '/public/images/profile/' . $identity . '/albums/*', GLOB_ONLYDIR) as $dir) {
        $album_name = basename($dir);

        $files[$album_name] = glob($dir . '/*.{jpg,png,gif,JPG,PNG,GIF}', GLOB_BRACE);
    }

    $form = new AddPhotosForm();

    $form->get('copy-from-album')->setValueOptions(array($album_name));

    return new ViewModel(array('form' => $form, 'files' => $files));
}

我知道它与 $album_name 有关,但我不知道如何使用它来获取所有目录(如果我尝试通过 [] 写入 $album_name) ,我收到

的警告
`Warning: Illegal offset type in C:\xampp\htdocs\module\Members\src\Members\Controller\ProfileController.php on line 197`

这是 $files[$album_name] = glob($dir . '/*.{jpg,png,gif,JPG,PNG,GIF}', GLOB_BRACE); 行。

正如我所说,我不知道如何编辑它以获取所有目录。

如有任何帮助,我们将不胜感激。

谢谢!

这是我要描述的内容的屏幕截图:http://imgur.com/OGifNG9 (存在多个目录,但 select 菜单中只列出一个)。

我真的建议用工厂来做。使用工厂,您只需编写一次此代码,就可以在代码中的其他任何地方使用它。出于面向对象的原因,其中一切都应该是一个对象,我建议使用 PHP 自己的 DirectoryIterator class 而不是 glob。控制器中的代码应尽可能小。请查看以下示例代码。

带有目录迭代器的表单工厂

表单工厂使用表单实例所需的一切为您初始化表单 class,因此此代码不会显示在控制器中。例如,您可以将其重新用于继承的编辑表单。

<?php
namespace Application\Form\Factory;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Application\Form\AddPhotosForm;

class AddPhotosFormFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $oServiceLocator)
    {
        $oParentLocator = $oServiceLocator->getServiceLocator();

        // please adjust the dir path - this is only an example
        $aDirectories = [];
        $oIterator = new \DirectoryIterator(__DIR__);
        
        // iterate and get all dirs existing in the path
        foreach ($oIterator as $oFileinfo) {
            if ($oFileinfo->isDir() && !$oFileinfo->isDot()) {
                $aDirectories[$oFileinfo->key()] = $oFileinfo->getFilename();
            }
        }

        // set option attribute for select element with key => value array of found dirs
        $oForm = new AddPhotosForm();
        $oForm->get('mySelectElement')
            ->setAttributes('options', $aDirectories);

        return $oForm;
    }
}

这就是工厂本身的全部。您唯一需要做的就是将其写在您的 module.config.php 文件中。

...
'form_elements' => [
    'factories' => [
        AddPhotosForm::class => AddPhotosFormFactory::class,
    ],
],
...

使用 ::class 不仅可以清理一切,还会导致使用更少的字符串,这使得 IDE 中的内容更容易记住,并且可以自动完成 class 个名称。

控制器

工厂我们清理了控制器。在控制器中代码应该尽可能小。使用工厂是许多问题的解决方案,这些问题可能会在后面的编码过程中发生。因此,请始终保持干净和简单。

...
public function indexAction()
{
    $oForm = $this->getServiceManager()
        ->get('FormElementManager')
        ->get(AddPhotosForm::class);

    return [
        'form' => $oForm,
    }
}

到目前为止控制器就到此为止。您的 select 元件是在工厂中填充的,您的控制器易于理解并且应该尽可能小。