在PHP中,SPLFileObject允许将文件视为迭代器.
然而,有一种我不理解的行为.当您在对象上调用next()时,它会增加key()的值,但不会使文件中的行前进,除非您在每次迭代时调用current().SPL文档声明key()返回当前行号.
代码重现:
的test.txt
0
1
2
3
Run Code Online (Sandbox Code Playgroud)
iterator.php
<?php
$fi = new SPLFileObject('test.txt');
echo $fi->current() . "\n"; // prints 0
echo $fi->key() . "\n"; //prints 0
$fi->next();
$fi->next();
$fi->next();
echo $fi->current() . "\n"; // prints 1, expecting 3
echo $fi->key() . "\n"; //prints 3
Run Code Online (Sandbox Code Playgroud)
从我所看到的,下一个不是在这个部分工作.如果我这样使用它会提前:
iterator_fix.php
<?php
$fi = new SPLFileObject('test.txt');
echo $fi->current() . "\n"; // prints 0
echo $fi->key() . "\n"; //prints 0
$fi->next();
$fi->current();
$fi->next();
$fi->current();
$fi->next();
echo $fi->current() . "\n"; // prints 3 as expected
echo …Run Code Online (Sandbox Code Playgroud) 简单的目录迭代器,它是递归的并显示所有文件和目录/子目录.
我没有看到任何内置的功能,以排除某些文件类型,例如在下面的例子中,我不希望输出的任何图像相关的文件,如.jpg,.png等我知道有这样做的几种方法,寻求建议哪个是最好的.
$scan_it = new RecursiveDirectoryIterator("/example_dir");
 foreach(new RecursiveIteratorIterator($scan_it) as $file) {
  echo $file;
  }
Run Code Online (Sandbox Code Playgroud) 通过SPL迭代器递归扫描目录的标准方法是:
$files = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($path),
    RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($files as $file) {
    print $file->getPathname() . PHP_EOL;
}
Run Code Online (Sandbox Code Playgroud)
我想要一组可组合的过滤器应用于我的递归文件搜索.我正在使用a RecursiveDirectoryIterator来扫描目录结构.
我想在我的目录结构中应用多个过滤器.
我的设置代码:
$filters = new FilterRuleset(
    new RecursiveDirectoryIterator($path)
);
$filters->addFilter(new FilterLapsedDirs);
$filters->addFilter(new IncludeExtension('wav'));
$files = new RecursiveIteratorIterator(
    $filters, RecursiveIteratorIterator::CHILD_FIRST
);
Run Code Online (Sandbox Code Playgroud)
我以为我可以使用规则集来应用N个过滤器:
class FilterRuleset extends RecursiveFilterIterator {
    private $filters = array();
    public function addFilter($filter) {
        $this->filters[] = $filter;
    }
    public function accept() {
        $file = $this->current();
        foreach ($this->filters as $filter) {
            if (!$filter->accept($file)) {
                return false;
            }
        }
        return …Run Code Online (Sandbox Code Playgroud) 我创建的自动加载类的简单脚本,但是当我使用class_exists的spl_autoload_register是执行,例如:
<?php
function autoLoadClass($name) {
    echo 'spl_autoload_register: ', $name, '<br>';
}
spl_autoload_register('autoLoadClass');
class_exists('Foo');
class_exists('Bar');
class_exists('Foo\\Bar');
Run Code Online (Sandbox Code Playgroud)
输出:
spl_autoload_register:Foo
spl_autoload_register:Bar
spl_autoload_register:Foo\Bar
是对的吗?有没有办法让"spl_autoload"忽略调用"class_exists"?
我的问题是,当我使用命名空间时,我无法使用标准 PHP 库的 RecursiveIteratorIterator 类。以下代码:
<?php namespace mynamespace;
    $arr = Array("abc", Array("def", "ghi", Array("jkl")));
    $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr));
    $result = iterator_to_array($it, false);
?>
Run Code Online (Sandbox Code Playgroud)
返回:
PHP 致命错误:未捕获错误:在...中找不到类“mynamespace\RecursiveIteratorIterator”
$arrayIter = new ArrayIterator( array(1, 2) );
$iterIter = new IteratorIterator($arrayIter);
var_dump($iterIter->valid()); //false
var_dump($arrayIter->valid()); //true
Run Code Online (Sandbox Code Playgroud)
如果我先调用$ iterIter-> rewind(),则$ iterIter-> valid()为true.我很好奇为什么要调用rewind().我想它有充分的理由,但我希望它只是在内部迭代器处于的任何状态下开始迭代,并在开始迭代之前将其作为回退选项.
调用next()似乎也把它置于"有效"状态(虽然它前进到下一个位置,表明它先前处于第一个位置).
$arrayIter = new ArrayIterator(array(1,2));
$iterIter = new IteratorIterator($arrayIter);
$iterIter->next();
var_dump($iterIter->valid()); 
Run Code Online (Sandbox Code Playgroud)
同样,我很好奇为什么我需要调用rewind(),尽管内部迭代器处于有效状态.
我在 Informix 数据库上有一个存储过程。我想从该过程的执行中获得一些变量。
我不知道如何创建存储过程。
这是我到目前为止:
CREATE PROCEDURE foo()
RETURN somebar;
END PROCEDURE;
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我收到一个错误:
DEFINE somebar
Run Code Online (Sandbox Code Playgroud)
我想做这个:
execute procedure foo() into bar;
Run Code Online (Sandbox Code Playgroud)
如何执行过程 foo() 并将返回值放入 bar?
我的应用程序需要生成一个具有data类型数组的大属性的对象的json .数组需要在收集数据库输出时保留在内存中,并且只有在数组完成后才能确定某些属性.
复杂性:数组是基于数字的,并且必须在json输出中显示,因此直接json_encode()不是一个选项.
为了在像RasPi这样的低规格机器上实现这一点,我研究了修剪内存消耗:
SPLFixedArraystring和pack()这两种方法都会处理数组存储内存问题,但在使用JSON进行编码时会失败.
我已经研究了实现JsonSerializable但是因为它强制用户返回结果,然后在Json中编码我回到了
public function jsonSerialize() {
    return $this->toArray();
}
Run Code Online (Sandbox Code Playgroud)
它有相同的记忆问题.
zendframework/Component_ZendJson看起来很有希望,因为它寻找具有toJson()提供自己的编码的方法的对象string而不是object.
我想知道是否有更好的选择不会给内存问题?
基本上SplPriorityQueueclass是使用max heapalgoritm 的堆.
我不明白为什么在文档中应该是a prioritized queue,因为a queue是一个FIFO集合(先进先出) - 但是因为SplPriorityQueue它依赖priority variable于比较函数,为什么它是一个队列?
为什么班级不仅仅是一个SplPriorityCollection?!
受Mark Baker的启发评论我测试了比较功能的行为,当所有项目的优先级相同时,结果表明具有相同优先级的集合不是FIFO
$objPQ = new SplPriorityQueue(); 
$objPQ->insert('A', 1); 
$objPQ->insert('B', 1); 
$objPQ->insert('C', 1); 
$objPQ->insert('D', 1); 
$objPQ->insert('E', 1); 
$objPQ->insert('F', 1);
$objPQ->insert('G', 1);
foreach($objPQ as $val) {
    echo $val . "\n";
}
Run Code Online (Sandbox Code Playgroud)
输出:
A G F E D C B
Run Code Online (Sandbox Code Playgroud) 我已经在 Stackoverflow 上对这个主题进行了一些搜索,但是据我所知,我没有将数组视为字符串?
我收到的消息是:
第 42 行 X 中的数组到字符串转换
我的代码的第 42 行是一个foreach循环的开始:
foreach ($collection as $element) {
Run Code Online (Sandbox Code Playgroud)
Variable$collection是一个基于数据库输出的缓存迭代器:
$collection=new \CachingIterator(new \ArrayIterator($this->dbData));
如果我print_r()打开$this->dbData,我肯定会得到一个数组:
Array
(
    [0] => Array
        (
            [c_id] => A
 )
    [1] => Array
        (
            [c_id] => B
)
Run Code Online (Sandbox Code Playgroud)
所以,总结一下:
ArrayIterator()期望一个arrayas 参数CachingIterator()期望一个Iteratoras 参数foreach()可以循环IteratorTL;DR我真的不确定我在这里将什么视为字符串?
编辑添加....
即使我大大简化了我的代码,我仍然可以重现:
<?php
error_reporting (E_ALL | E_STRICT);
ini_set ('display_errors', 1);
$arrX=array(array("c_id"=>"A"),array("c_id"=>"B"));
$collection=new …Run Code Online (Sandbox Code Playgroud) spl ×10
php ×9
iterator ×3
arrays ×1
autoloader ×1
directory ×1
file ×1
informix ×1
json ×1
namespaces ×1