【发布时间】:2015-11-24 15:18:02
【问题描述】:
因此,为了了解更多有关 Android 开发的知识,在学习 Java 编程书籍时,我遇到了 JSONObject 和 JSONArray。 经过一番研究,我编写了一个 php 脚本来读取目标目录的内容,输出是一个 JSON 文件,其中包含足够的信息来解析我的学习资料中的 Java 类。
唯一的问题是,我接触 php 已经有好几年了,我从几个来源汇总的部分是我唯一能理解的部分 - 所以情况如下:
如何从我的结果中过滤掉(在将它们添加到我的 JSON 文件之前)排除数组(文件和/或目录),例如:“@eaDir”、“Thumbs.db”、“.DS_File”等。
这里是有问题的代码:
#!/usr/bin/php
<?php
/* Run with: php [filename].php /path/to/folder/
Outputs file_list.json in target folder */
// Where are we running on?
if (PHP_SAPI === 'cli') {
$argument1 = $argv[1];
$argument2 = $argv[2];
}
else {
$argument1 = $_GET['argument1'];
$argument2 = $_GET['argument2'];
}
// Set output dir and file
$out = $argument1 . '/file_list.json';
/*
* @param Array $types
* @abstract Array of allowed file types
*/
$types = Array ('mp3', 'ogg');
if (!isset($argv[1]))
exit("Must specify a directory to scan\n");
if (!is_dir($argv[1]))
exit($argv[1]."' is not a directory\n");
/*
* @name getList
* @param Array $dir
* @param Array $types
* @abstract Recursively iterates over specified directory
* populating array based on array of file extensions
* @return Array $files
*/
function getList($dir, $types) {
$it = new RecursiveDirectoryIterator($dir);
foreach(new RecursiveIteratorIterator($it) as $file) {
if (in_array(strtolower(array_pop(explode('.', $file))), $types)) {
$files[] = $file->__toString();
}
}
return $files;
}
/*
* @name getDetails
* @param Array $dir
* @param Array $types
* @abstract Recursively iterates over specified directory
* populating array with details of each file
* @return Array $files
*/
function getDetails($types, $array)
{
foreach($types as $type)
{
foreach($array as $file)
{
if (strcasecmp($type, array_pop(explode('.', $file))) == 0) {
$files[$type][basename($file)];
$files[$type][basename($file)]['source'] = $file;
$files[$type][basename($file)]['size'] = filesize($file);
}
}
}
return array('files'=>$files);
}
if (!function_exists('json_encode')) {
/*
* @name json_encode
* @param Mixed $val
* @abstract Alternate emulated json_encode function
* @return Object $res
*/
function json_encode($val)
{
if (is_string($val)) return '"'.addslashes($val).'"';
if (is_numeric($val)) return $val;
if ($val === null) return 'null';
if ($val === true) return 'true';
if ($val === false) return 'false';
$assoc = false;
$i = 0;
foreach ($val as $k=>$v){
if ($k !== $i++){
$assoc = true;
break;
}
}
$res = array();
foreach ($val as $k=>$v){
$v = json_encode($v);
if ($assoc){
$k = '"'.addslashes($k).'"';
$v = $k.':'.$v;
}
$res[] = $v;
}
$res = implode(',', $res);
return ($assoc)? '{'.$res.'}' : '['.$res.']';
}
}
/* Open file in write mode */
$fp = fopen($out, 'w');
/* Run application & save file */
fwrite($fp, json_encode(getDetails($types, getList($argv[1], $types))));
/* Close file */
fclose($fp);
exit();
我在 Synology DS1513+ 上运行此程序,它总是吐出名称为 @eaDir 的目录。这是我禁用的索引过程,但会在下一次更新时恢复(有时在重新启动后)。 我想添加更多文件类型,而不必担心脚本会检查我上面提到的目录。
我怎样才能做到这一点?
编辑: 经过更多的阅读和研究,我添加了一个嵌套的 if 条件来过滤掉目录,这是包含更改的代码:
#!/usr/bin/php
<?php
/* Run with: php [filename].php /path/to/folder/
Outputs file_list.json in target folder */
// Where are we running on?
if (PHP_SAPI === 'cli') {
$argument1 = $argv[1];
$argument2 = $argv[2];
} else {
$argument1 = $_GET['argument1'];
$argument2 = $_GET['argument2'];
}
// Set output dir and file
$out = $argument1 . '/file_list.json';
/*
* @param Array $types
* @abstract Array of allowed file types
*/
$types = ['mp3', 'ogg', 'jpg'];
$ignoreDir = ['@eaDir'];
if (!isset($argv[1])) {
exit("Must specify a directory to scan\n");
}
if (!is_dir($argv[1])) {
exit($argv[1] . "' is not a directory\n");
}
/*
* @name getList
* @param Array $dir
* @param Array $types
* @param Array $ignoreDir
* @abstract Recursively iterates over specified directory
* populating array based on array of file extensions
* while ignoring directories specified in ignoreDir
* @return Array $files
*/
function getList($dir, $types, $ignoreDir) {
$it = new RecursiveDirectoryIterator($dir);
foreach (new RecursiveIteratorIterator($it) as $file) {
if (in_array(strtolower(array_pop(explode('.', $file))), $types)) {
if (!in_array($it, $ignoreDir)) {
$files[] = $file->__toString();
}
}
}
return $files;
}
/*
* @name getDetails
* @param Array $dir
* @param Array $types
* @abstract Recursively iterates over specified directory
* populating array with details of each file
* @return Array $files
*/
function getDetails($types, $array) {
foreach ($types as $type) {
foreach ($array as $file) {
if (strcasecmp($type, array_pop(explode('.', $file))) == 0) {
$files[$type][basename($file)]['name'] = basename($file);
$files[$type][basename($file)]['size'] = filesize($file);
$files[$type][basename($file)]['source'] = $file;
$files[$type][basename($file)]['date'] = date ("F d Y H:i:s", filemtime($file));
}
}
}
return array('files' => $files);
}
if (!function_exists('json_encode')) {
/*
* @name json_encode
* @param Mixed $val
* @abstract Alternate emulated json_encode function
* @return Object $res
*/
function json_encode($val)
{
if (is_string($val)) return '"'.addslashes($val).'"';
if (is_numeric($val)) return $val;
if ($val === null) return 'null';
if ($val === true) return 'true';
if ($val === false) return 'false';
$assoc = false;
$i = 0;
foreach ($val as $k=>$v){
if ($k !== $i++){
$assoc = true;
break;
}
}
$res = array();
foreach ($val as $k=>$v){
$v = json_encode($v);
if ($assoc){
$k = '"'.addslashes($k).'"';
$v = $k.':'.$v;
}
$res[] = $v;
}
$res = implode(',', $res);
return ($assoc)? '{'.$res.'}' : '['.$res.']';
}
}
/* Open file in write mode */
$fp = fopen($out, 'w');
/* Run application & save file */
fwrite($fp, json_encode(getDetails($types, getList($argv[1], $types, $ignoreDir)), JSON_PRETTY_PRINT));
/* Close file */
fclose($fp);
exit();
我仍然有兴趣了解有关 RecursiveDirectoryIterator 如何使用过滤器的更多信息,但到目前为止,这可以满足我的需求。
【问题讨论】: