# Directoryiterator / preg_match behavior

- Thread: https://externals.io/message/12530
- Original archive: https://news-web.php.net/php.internals/12530
- Started by Aaron Wormus on 2004-09-02T00:33:10+00:00
- Messages: 3
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #12530 — Aaron Wormus — 2004-09-02T00:33:10+00:00

URL: https://externals.io/message/12530#12530

When playing with PHP5 I tried the following code:

foreach (new DirectoryIterator('.') as $file) {
     if (preg_match("/^\./", $file)){
         continue;
     }
     print "<a href='$file'>$file</a><br />\n";
}

the result was unexpected, but after an IRC session and reading the 
manual all became clear.

My question is if the following code is the expected behaviour? I'm 
running `E_STRICT` and would expect at least a warning...

foreach (new DirectoryIterator('.') as $file) {
     echo "<pre>";
     var_dump($file);

     if (preg_match("/xxx/", $file)){
         // Why is this breaking $file??
	//    without even a warning
     }

     var_dump($file);
     echo "</pre>";
}

strpos and substr work fine, and I was kindly informed that they do a 
convert_to_string_ex() on the object before they do their thing. Would 
it be breaking anything if, for consistancy, the same functionality was 
put into preg_match?

I'm all sorted out now but thought to send this off incase it was indeed 
a bug somewhere.

Thanks

Aaron

---

## #12539 — Curt Zirzow — 2004-09-02T04:24:11+00:00

URL: https://externals.io/message/12530#12539 · In reply to: #12530

* Thus wrote Aaron Wormus:
> 
> foreach (new DirectoryIterator('.') as $file) {
>     echo "<pre>";
>     var_dump($file);
> 
>     if (preg_match("/xxx/", $file)){
>         // Why is this breaking $file??
> 	//    without even a warning
>     }
> 
>     var_dump($file);
>     echo "</pre>";
> }


This probably needs some attention, here are some related issues that
I've came accross trying to find out why the above was happening:


Test 1: ($file holds last type conversion)
<?php
foreach (new DirectoryIterator('.') as $file) {
    echo "\n--\n";
    var_dump($file);
    preg_match("/xxx/", $file);
    var_dump($file);
    echo "\n--";
}

Output:
Object(DirectoryIterator)#1 (0) {
}
string(1) "."
--
--
string(1) "."
string(1) "."
--
...


Test 2: (working example)
----------
<?php
$d = new DirectoryIterator('.');
foreach ($d as &$file) {
    echo "\n--\n";
    var_dump($file);
    preg_match("/xxx/", $file);
    var_dump($file);
    echo "\n--";
}

Output:
--
object(DirectoryIterator)#1 (0) {
}
object(DirectoryIterator)#1 (0) {
}
--
--
object(DirectoryIterator)#1 (0) {
}
object(DirectoryIterator)#1 (0) {
}
--

...

Test 3: (completly fails)
----------
<?php
foreach (new DirectoryIterator('.') as &$file) {
    echo "\n--\n";
    var_dump($file);
    preg_match("/xxx/", $file);
    var_dump($file);
    echo "\n--\n";
}

Output:
PHP Parse error:  syntax error, unexpected `T_STRING` in test.php on line 2


This appears to be a definate bug somewhere and I cant spot it atm.


Curt
-- 
First, let me assure you that this is not one of those shady pyramid schemes
you've been hearing about.  No, sir.  Our model is the trapezoid!

---

## #12548 — Andrei Zmievski — 2004-09-02T17:43:06+00:00

URL: https://externals.io/message/12530#12548 · In reply to: #12539

> Test 1: ($file holds last type conversion)
> <?php
> foreach (new DirectoryIterator('.') as $file) {
>     echo "\n--\n";
>     var_dump($file);
>     preg_match("/xxx/", $file);
>     var_dump($file);
>     echo "\n--";
> }
> 
> Output:
> Object(DirectoryIterator)#1 (0) {
> }
> string(1) "."
> --
> --
> string(1) "."
> string(1) "."
> --
> ...

The culprit is this piece of code in zend_parse_arg_impl():

	case IS_OBJECT: {
		if (Z_OBJ_HANDLER_PP(arg, cast_object)
			&& Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_STRING, 0 TSRMLS_CC) == SUCCESS) {
			*pl = Z_STRLEN_PP(arg);
			*p = Z_STRVAL_PP(arg);
			break;
		}

The cast_object handler overwrites the value in *arg and that's why the
original variable changes type. I think Andi made this change on Dec 02,
2003. I can see the rationale behind not using a new var for the
conversion, because then we have to keep track of it and release it
somehow, but changing variable types is not good either. Andi, any
suggestions?

- Andrei
