La solution rapide et facile
Vous pourriez faire votre vie plus facile et utilisez un DirectoryIterator
pour parcourir le répertoire.
echo '<select name="vids" size="4">';
foreach(new DirectoryIterator('/path/to/videos') as $file) {
if($file->isFile() === TRUE && $file->getBasename() !== '.DS_Store') {
printf("<option>%s</option>\n", htmlentities($file->getBasename()));
}
}
echo '</select>';
Amélioration: Découplage Répertoire Filtrage du bâtiment selectbox
Si vous voulez découpler la logique de filtrage de la boucle foreach
, vous pouvez sous-classe une FilterIterator
à capsule logique dans c'est accept()
méthode . Le DirectoryIterator
doit être ensuite enveloppé dans le FilterIterator
. Le point principal est bien sûr réutilisabilité:
class MyFilter extends FilterIterator
{
public function accept()
{
return $this->current()->isFile() === TRUE &&
$this->current()->getBasename() !== '.DS_Store';
}
}
$iterator = new MyFilter(new DirectoryIterator('/path/to/videos'));
Lorsque vous utilisez foreach
sur une iterator filtrée, il déclenchera automatiquement accept()
. Si accept()
renvoie FALSE
, l'élément en cours sera filtré dans l'itération.
Vous créez le selectbox comme ça alors:
echo '<select name="vids" size="4">';
foreach($iterator as $file) {
printf("<option>%s</option>\n", htmlentities($file->getBasename()));
}
echo '</select>';
Alternative à sous-classement FilterIterator
Si vous êtes trop paresseux pour écrire un FilterIterator
séparé ou pense qu'il est tout simplement pas la peine pour un cas spécifique ou déjà avoir des validateurs quelque part et ne veulent pas dupliquer leur code, mais veulent toujours découpler la création Filtering et SelectBox, vous pouvez également utiliser cette coutume FilterChainIterator
et ajouter callbacks à elle:
$iterator = new FilterChainIterator(new DirectoryIterator('/path/to/videos'));
$iterator->addCallback(function($file) {
return $file->isFile() === TRUE &&
$file->getBasename() !== '.DS_Store';});
La création de selectbox serait le même que celui indiqué ci-dessus.
Amélioration: faire de la création de selectbox réutilisable
En outre, si vous voulez faire de la création de selectbox réutilisable, pourquoi ne pas créer une aide pour elle. Ci-dessous est un très simple qui utilise DOM pour créer le code HTML réel. Vous passez une Iterator et créerez le code HTML pour vous lorsque vous appelez est la méthode render()
ou l'utiliser dans un contexte de chaîne:
class SelectBox
{
protected $iterator;
public function __construct(Iterator $iterator)
{
$this->iterator = $iterator;
}
public function render()
{
$dom = new DOMDocument;
$dom->formatOutput = TRUE;
$dom->loadXml('<select name="vids"/>');
$dom->documentElement->appendChild(new DOMElement('option', 'Pick One'));
foreach($this->iterator as $option) {
$dom->documentElement->appendChild(
new DOMElement('option', $option));
}
return $dom->saveXml($dom->documentElement);
}
public function __toString()
{
return $this->render();
}
}
Et puis imprimer un selectbox d'un itérateur est aussi simple que
echo new SelectBox(new MyFilter(new DirectoryIterator('/path/to/videos')));
C'est assez flexible, étant donné qu'il y a des itérateurs pour tout. Par exemple
echo new SelectBox(new ArrayIterator(array('foo', 'bar', 'baz')));
donnerait une manière ordonnée au format
<select>
<option>Pick One</option>
<option>foo</option>
<option>bar</option>
<option>baz</option>
</select>
Pourquoi l'opérateur identique (===) dans '$ file-> isFile() === TRUE'? J'imagine que juste '$ file-> isFile()' fonctionnerait de la même manière. –
+1 pour DirectoryIterator –