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
- 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!
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,
- 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