[PHP] Iterators.

2010-12-03 Thread Richard Quadling
Hi.

OK. I'm stuck. I just can't work this out.

I like SPL. I like the re-usability. It seems right. But I just can't
work it out.

I want to read through a file system, looking for files of a particular type.
I want to ignore and not traverse any folder with a specific name
anywhere in the directory tree.
I want to examine the contents of the file with a set of regular
expressions and call a closure for each match for each regex which
will replace and replace the file with the amended one.
I want to get a list of the files altered along with which regex and
the number of changes.

The part I'm really stuck on is working out what elements of the SPL
fit my issue the best and what bits I have to implement myself, with
regard to the file system iteration and filtering.

The tree is pretty large - just over 5,000 files with 5,700
directories. The deepest file is 12 levels down.


Now I know someone could supply a solution not using the SPL. I've got
one of those. But trying to use the SPL just seems to awkward. Too
many choices. Too many things with the same name

Iterator, RecursiveIterator, RecusiverIteratorIterator.

An Iterator suggests that it can work on a simple array ($argv for
example). A non SPL variant would be foreach().
A RecursiveIterator suggests it can iterator recursively on nested
data (a file system for example). Using a function which uses
scandir() and calls itself for a directory would look like a recursive
iterator.

So what does a RecursiveIteratorIterator do? Documentation says Can
be used to iterate through recursive iterators..

But that sounds daft. The RecursiveIterator is the handling the
parent/child/tree navigation (isn't it - if not why not?)


The name really doesn't help me to understand what's going on or what its for.


Is there any place that can describe the SPL in a different way.

I know it's probably just me, but it really seems like I'm only just
scratching the surface. And not really getting anywhere.


-- 
Richard Quadling
Twitter : EE : Zend
@RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Iterators.

2010-12-03 Thread Daniel P. Brown
On Fri, Dec 3, 2010 at 08:09, Richard Quadling rquadl...@gmail.com wrote:

 Now I know someone could supply a solution not using the SPL. I've got
 one of those. But trying to use the SPL just seems to awkward. Too
 many choices. Too many things with the same name

I put an example up on the list this week, actually.  Had you seen
it?  If not, or if you can't find it in the archives, let me know
(even on chat) and I'll repost it.

-- 
/Daniel P. Brown
Dedicated Servers, Cloud and Cloud Hybrid Solutions, VPS, Hosting
(866-) 725-4321
http://www.parasane.net/

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Iterators.

2010-12-03 Thread Nathan Nobbe
On Fri, Dec 3, 2010 at 6:09 AM, Richard Quadling rquadl...@gmail.comwrote:

 Hi.

 OK. I'm stuck. I just can't work this out.

 I like SPL. I like the re-usability. It seems right. But I just can't
 work it out.

 I want to read through a file system, looking for files of a particular
 type.

I want to ignore and not traverse any folder with a specific name
 anywhere in the directory tree.
 I want to examine the contents of the file with a set of regular
 expressions and call a closure for each match for each regex which
 will replace and replace the file with the amended one.
 I want to get a list of the files altered along with which regex and
 the number of changes.


That could work with DirectoryIterator, a subclass thereof, or a combination
of DirectoryIterator and FilterIterator.



 The part I'm really stuck on is working out what elements of the SPL
 fit my issue the best and what bits I have to implement myself, with
 regard to the file system iteration and filtering.


You have a few options as I mentioned above.  Depends on whether you want to
encapsulate the logic you're mentioning or if you just want to use it in one
place.

The simplest way to go is DirectoryIterator, driving the iteration via
foreach, and your custom logic goes inside the body of the foreach.

foreach(new DirectoryIterator('.') as $oFile)
{
// custom, one-off logic here
// ex. skip directories w/ a given name
if($oFile-isDir()  $oFile-getFilename() == 'LeaveMeAlone')
  continue;
}

Issue here is the logic portion is not very re-usable.  You could easily
move the logic into a subclass though if you want to have re-usable logic.
 Most likely this will end up in the current() function, however, you may
want to consider dividing up the logic between a DirectoryIterator subclass
and a FilterIterator implementation.

FilterIterator lends itself to the 'should I operate on this node' question,
so when you're talking about looking for files of a certain type and folders
of a certain name, that sounds like it should go in a FilterIterator.
 However, at a cursory glance, if you want to skip entire sets of children
based on the name of a given directory, you'll likely need to iterate a
RecursiveDirectoryIterator yourself of subclass RecursiveIteratorIterator.

For the other part, w/ the closure, changing files and tracking which files
have been changed, that sounds best for a DirectoryIterator subclass.  And
if you're planning on handling multiple directories, w/ nested children, go
for a RecursiveDirectoryIterator.


 The tree is pretty large - just over 5,000 files with 5,700
 directories. The deepest file is 12 levels down.


 Now I know someone could supply a solution not using the SPL. I've got
 one of those. But trying to use the SPL just seems to awkward. Too
 many choices. Too many things with the same name

 Iterator, RecursiveIterator, RecusiverIteratorIterator.


Once you've messed with the classes for a bit, the choices become much more
natural and obvious, I too was overwhelmed by the sheer number of classes
when I first had a look.


 An Iterator suggests that it can work on a simple array ($argv for
 example). A non SPL variant would be foreach().
 A RecursiveIterator suggests it can iterator recursively on nested
 data (a file system for example). Using a function which uses
 scandir() and calls itself for a directory would look like a recursive
 iterator.

 So what does a RecursiveIteratorIterator do? Documentation says Can
 be used to iterate through recursive iterators..


The RecursiveIteratorIterator is best thought as a tool to 'flatten' out
a hierarchal data structure.  So imagine having 1 foreach block and every
node in the tree magically gets driven through it at some point.  Without
RecursiveIteratorIterator you have to be bothered to make calls to the
hasChildren() / getChildren() methods of the RecursiveIterator, and then
iterate though the child Iterators yourself.  RecursiveIteratorIterator just
packages that logic up in a standard way.


 But that sounds daft. The RecursiveIterator is the handling the
 parent/child/tree navigation (isn't it - if not why not?)


 The name really doesn't help me to understand what's going on or what its
 for.


The docs are a little rough, but manageable after you've messed w/ the
classes a bit, but I know what you mean.


 Is there any place that can describe the SPL in a different way.


Head to the homepage of the original SPL docs,

http://www.php.net/~helly/php/ext/spl/

then search for Some articles about SPL these are quite useful when
getting started w/ the Iterators.

I know it's probably just me, but it really seems like I'm only just
 scratching the surface. And not really getting anywhere.


I mean, I don't know anything but am glad to help where I can.  Not everyone
cares for Iterators, but they're a great way to package re-usable logic and
manage OO collections.  Of course I doubt PHP will ever have type safe
collections :O

Here's a quick 

Re: [PHP] Iterators.

2010-12-03 Thread Richard Quadling
On 3 December 2010 16:56, Nathan Nobbe quickshif...@gmail.com wrote:
 On Fri, Dec 3, 2010 at 6:09 AM, Richard Quadling rquadl...@gmail.com
 wrote:

 Hi.

 OK. I'm stuck. I just can't work this out.

 I like SPL. I like the re-usability. It seems right. But I just can't
 work it out.

 I want to read through a file system, looking for files of a particular
 type.

 I want to ignore and not traverse any folder with a specific name
 anywhere in the directory tree.
 I want to examine the contents of the file with a set of regular
 expressions and call a closure for each match for each regex which
 will replace and replace the file with the amended one.
 I want to get a list of the files altered along with which regex and
 the number of changes.

 That could work with DirectoryIterator, a subclass thereof, or a combination
 of DirectoryIterator and FilterIterator.



 The part I'm really stuck on is working out what elements of the SPL
 fit my issue the best and what bits I have to implement myself, with
 regard to the file system iteration and filtering.

 You have a few options as I mentioned above.  Depends on whether you want to
 encapsulate the logic you're mentioning or if you just want to use it in one
 place.
 The simplest way to go is DirectoryIterator, driving the iteration via
 foreach, and your custom logic goes inside the body of the foreach.
 foreach(new DirectoryIterator('.') as $oFile)
 {
     // custom, one-off logic here
     // ex. skip directories w/ a given name
     if($oFile-isDir()  $oFile-getFilename() == 'LeaveMeAlone')
       continue;
 }
 Issue here is the logic portion is not very re-usable.  You could easily
 move the logic into a subclass though if you want to have re-usable logic.
  Most likely this will end up in the current() function, however, you may
 want to consider dividing up the logic between a DirectoryIterator subclass
 and a FilterIterator implementation.
 FilterIterator lends itself to the 'should I operate on this node' question,
 so when you're talking about looking for files of a certain type and folders
 of a certain name, that sounds like it should go in a FilterIterator.
  However, at a cursory glance, if you want to skip entire sets of children
 based on the name of a given directory, you'll likely need to iterate a
 RecursiveDirectoryIterator yourself of subclass RecursiveIteratorIterator.
 For the other part, w/ the closure, changing files and tracking which files
 have been changed, that sounds best for a DirectoryIterator subclass.  And
 if you're planning on handling multiple directories, w/ nested children, go
 for a RecursiveDirectoryIterator.


 The tree is pretty large - just over 5,000 files with 5,700
 directories. The deepest file is 12 levels down.


 Now I know someone could supply a solution not using the SPL. I've got
 one of those. But trying to use the SPL just seems to awkward. Too
 many choices. Too many things with the same name

 Iterator, RecursiveIterator, RecusiverIteratorIterator.

 Once you've messed with the classes for a bit, the choices become much more
 natural and obvious, I too was overwhelmed by the sheer number of classes
 when I first had a look.


 An Iterator suggests that it can work on a simple array ($argv for
 example). A non SPL variant would be foreach().
 A RecursiveIterator suggests it can iterator recursively on nested
 data (a file system for example). Using a function which uses
 scandir() and calls itself for a directory would look like a recursive
 iterator.

 So what does a RecursiveIteratorIterator do? Documentation says Can
 be used to iterate through recursive iterators..

 The RecursiveIteratorIterator is best thought as a tool to 'flatten' out
 a hierarchal data structure.  So imagine having 1 foreach block and every
 node in the tree magically gets driven through it at some point.  Without
 RecursiveIteratorIterator you have to be bothered to make calls to the
 hasChildren() / getChildren() methods of the RecursiveIterator, and then
 iterate though the child Iterators yourself.  RecursiveIteratorIterator just
 packages that logic up in a standard way.


 But that sounds daft. The RecursiveIterator is the handling the
 parent/child/tree navigation (isn't it - if not why not?)


 The name really doesn't help me to understand what's going on or what its
 for.

 The docs are a little rough, but manageable after you've messed w/ the
 classes a bit, but I know what you mean.


 Is there any place that can describe the SPL in a different way.

 Head to the homepage of the original SPL docs,
 http://www.php.net/~helly/php/ext/spl/
 then search for Some articles about SPL these are quite useful when
 getting started w/ the Iterators.

 I know it's probably just me, but it really seems like I'm only just
 scratching the surface. And not really getting anywhere.

 I mean, I don't know anything but am glad to help where I can.  Not everyone
 cares for Iterators, but they're a great way to package re-usable logic 

[PHP] Iterators

2007-02-12 Thread Marc Weber


?php

function A()
{
  return new RecursiveArrayIterator(array(func_get_args()));
}
$a=iterator_to_array(new RecursiveIteratorIterator( A (A(2) , A (3,4),  
A(5,6;

var_dump($a);

?

I'd expect this to output an array containing 2,3,4,5,6.
But the result is:

array(2) {
  [0]=
  int(5)
  [1]=
  int(6)
}

What did I miss here?

Marc

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Iterators

2007-02-12 Thread Jochem Maas
Marc Weber wrote:
 
 ?php
 
 function A()
 {
   return new RecursiveArrayIterator(array(func_get_args()));
 }
 $a=iterator_to_array(new RecursiveIteratorIterator( A (A(2) , A (3,4),
 A(5,6;
 var_dump($a);
 
 ?
 
 I'd expect this to output an array containing 2,3,4,5,6.
 But the result is:
 
 array(2) {
   [0]=
   int(5)
   [1]=
   int(6)
 }
 
 What did I miss here?

how should we know with out seeing the iterator_to_array() definition?

function A() {
$a = func_get_args();
return new RecursiveArrayIterator(array($a));
}

$a = new RecursiveIteratorIterator( A(A(2) , A(3,4), A(5,6)) );
foreach ($a as $b) echo $b;


the above code outputs: 23456 - so the problem looks to be in your
iterator_to_array() function.

 
 Marc
 
 --PHP General Mailing List (http://www.php.net/)
 To unsubscribe, visit: http://www.php.net/unsub.php
 

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Iterators - seg faults again

2007-02-12 Thread Marc Weber
On Mon, 12 Feb 2007 20:33:08 +0100, Jochem Maas [EMAIL PROTECTED]  
wrote:




how should we know with out seeing the iterator_to_array() definition?

iterator_to_array() function is from php.
See http://de2.php.net/manual/en/function.iterator-to-array.php


Here is another testcase.
Why is this happening? Can you confirm this? What has to be done different?
If you don't get these results (sef faults (I still want to get 2,3,4,5,6)  
would you mind

telling me which version of php you are using?

The file is t.php and its appended at the bottom (cat t.php)

Thanks in advance Marc


[EMAIL PROTECTED] /tmp $ php t.php
 ==
 tescase is !!0!!
 ==
are the following two results the same?
1 :array(2) {
  [0]=
  int(5)
  [1]=
  int(6)
}
2 :current element in my_iterator_to_arrayArray
current element in my_iterator_to_array2
current element in my_iterator_to_array3
current element in my_iterator_to_array4
current element in my_iterator_to_array5
current element in my_iterator_to_array6
array(6) {
  [0]=
  array(3) {
[0]=
Segmentation fault


[EMAIL PROTECTED] /tmp $ php t.php
 ==
 tescase is !!1!!
 ==
are the following two results the same?
1 :array(2) {
  [0]=
  int(5)
  [1]=
  int(6)
}
2 :

foreach does print what I want (23456), why ?
2
3
4
5
6


running for each the second time results in segfault again. Why ?
Segmentation fault


[EMAIL PROTECTED] /tmp $ php -v
PHP 5.1.6-pl6-gentoo (cli) (built: Feb 11 2007 02:37:11)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies


[EMAIL PROTECTED] /tmp $ cat t.php
?php
$testcase = 1;
echo  ==\n;
echo  tescase is !!$testcase!!\n;
echo  ==\n;

function A()
{
  $a = func_get_args();
  return new RecursiveArrayIterator(array(func_get_args()));
}

function my_iterator_to_array($it)
{
	  echo $it instanceof IteratorAggregate; // doesn't output anything so  
result is false. So I don't have to try calling getIterator manually

  $res = array();
  while ($it-valid()){
echo current element in my_iterator_to_array, $it-current(),\n;
$res[] = $it-current();
$it-next();
  }
  return $res;
}

echo are the following two results the same?\n;
echo 1 :;
	var_dump(iterator_to_array(new RecursiveIteratorIterator( A (A(2) , A  
(3,4), A(5,6);

echo 2 :;
if ($testcase == 0)
	  var_dump(my_iterator_to_array(new RecursiveIteratorIterator( A (A(2) ,  
A (3,4), A(5,6);


$ri = new RecursiveIteratorIterator( A (A(2) , A (3,4), A(5,6)));

echo \n\nforeach does print what I want (23456), why ?\n;
foreach( $ri as $v) echo $v\n;
// why does the second foreach cause a segfault here?
	echo \n\nrunning for each the second time results in segfault again. Why  
?\n;

foreach( $ri as $v) echo $v\n;


?

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Iterators - seg faults again

2007-02-12 Thread Roman Neuhauser
# [EMAIL PROTECTED] / 2007-02-12 23:34:21 +0100:
 Why is this happening? Can you confirm this? What has to be done different?
 If you don't get these results (sef faults (I still want to get 2,3,4,5,6)  
 would you mind
 telling me which version of php you are using?
 
 The file is t.php and its appended at the bottom (cat t.php)
 
 Thanks in advance Marc
 
 
 [EMAIL PROTECTED] /tmp $ php t.php
==
tescase is !!0!!
==
   are the following two results the same?
   1 :array(2) {
 [0]=
 int(5)
 [1]=
 int(6)
   }
   2 :current element in my_iterator_to_arrayArray
   current element in my_iterator_to_array2
   current element in my_iterator_to_array3
   current element in my_iterator_to_array4
   current element in my_iterator_to_array5
   current element in my_iterator_to_array6
   array(6) {
 [0]=
 array(3) {
   [0]=
   Segmentation fault
 
 
 [EMAIL PROTECTED] /tmp $ php t.php
==
tescase is !!1!!
==
   are the following two results the same?
   1 :array(2) {
 [0]=
 int(5)
 [1]=
 int(6)
   }
   2 :
 
   foreach does print what I want (23456), why ?
   2
   3
   4
   5
   6
 
 
   running for each the second time results in segfault again. Why ?
   Segmentation fault
 
 
 [EMAIL PROTECTED] /tmp $ php -v
   PHP 5.1.6-pl6-gentoo (cli) (built: Feb 11 2007 02:37:11)
   Copyright (c) 1997-2006 The PHP Group
   Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies
 
 
 [EMAIL PROTECTED] /tmp $ cat t.php
   ?php
   $testcase = 1;
   echo  ==\n;
   echo  tescase is !!$testcase!!\n;
   echo  ==\n;
 
   function A()
   {
 $a = func_get_args();
 return new RecursiveArrayIterator(array(func_get_args()));
   }
 
   function my_iterator_to_array($it)
   {
 echo $it instanceof IteratorAggregate; // doesn't output anything 
 so  result is false. So I don't have to try calling getIterator 
 manually
 $res = array();
 while ($it-valid()){
   echo current element in my_iterator_to_array, 
   $it-current(),\n;
   $res[] = $it-current();
   $it-next();
 }
 return $res;
   }
 
   echo are the following two results the same?\n;
   echo 1 :;
   var_dump(iterator_to_array(new RecursiveIteratorIterator( A (A(2) , 
   A  (3,4), A(5,6);
   echo 2 :;
   if ($testcase == 0)
 var_dump(my_iterator_to_array(new RecursiveIteratorIterator( A 
 (A(2) ,  A (3,4), A(5,6);
 
   $ri = new RecursiveIteratorIterator( A (A(2) , A (3,4), A(5,6)));
 
   echo \n\nforeach does print what I want (23456), why ?\n;
   foreach( $ri as $v) echo $v\n;
   // why does the second foreach cause a segfault here?
   echo \n\nrunning for each the second time results in segfault 
   again. Why  ?\n;
   foreach( $ri as $v) echo $v\n;


I get a nice row of ducks:

-rw---  1 roman  roman  2109440 Feb 12 23:09 php512.core
-rw---  1 roman  roman  2043904 Feb 12 23:09 php513.core
-rw---  1 roman  roman  2043904 Feb 12 23:09 php514.core
-rw---  1 roman  roman  2043904 Feb 12 23:09 php515.core
-rw---  1 roman  roman  2043904 Feb 12 23:09 php516.core
-rw---  1 roman  roman  2203648 Feb 12 23:09 php520.core
-rw---  1 roman  roman  1966080 Feb 12 23:09 php521.core

This is from 5.2.1:

#0  zend_std_object_get_class (object=0x7b03d0) at 
/usr/home/roman/install/php/php-5.2.1/Zend/zend_object_handlers.c:1044
zobj = (zend_object *) 0x8
#1  0x0046fe88 in zim_spl_Array_getChildren (ht=8061904, 
return_value=0x7b05e0, return_value_ptr=0x79dc78, 
this_ptr=0x7b03f8, return_value_used=1) at 
/usr/home/roman/install/php/php-5.2.1/ext/spl/spl_array.c:1386
entry = (zval **) 0x7b0268
intern = (spl_array_object *) 0x85c400
#2  0x00517a05 in zend_call_function (fci=0x7fffc870, 
fci_cache=0x7fffd018)
at /usr/home/roman/install/php/php-5.2.1/Zend/zend_execute_API.c:984
lcname = 0x1 Address 0x1 out of bounds
i = 4294952784
original_return_value = (zval **) 0x7fffc920
calling_symbol_table = (HashTable *) 0xb
original_function_state_ptr = (zend_function_state *) 0x7fffd018
original_op_array = (zend_op_array *) 0x7fffc750
original_opline_ptr = (zend_op **) 0x7fffc918
current_scope = (zend_class_entry *) 0x0
calling_scope = (zend_class_entry *) 0x85c400
check_scope_or_static = (zend_class_entry *) 0x0
current_this = (zval *) 0x0
execute_data = {opline = 0x0, function_state = {function_symbol_table = 
0x7afbe8, function = 0x85da00, reserved = {
  0x800b646e9, 0x7aca18, 0x0, 0x7aca08}}, fbc