-3

I'm using PHP 7.2.1

Consider below code :

<?php
namespace A\B\C;

const E_ERROR = 45;
function strlen($str)
{
    return strlen($str) - 1;
}

echo E_ERROR, "\n"; // prints "45"
echo INI_ALL, "\n"; // prints "7" - falls back to global INI_ALL

echo strlen('hi'), "\n"; // prints "1"
if (is_array('hi')) { // prints "is not array"
    echo "is array\n";
} else {
    echo "is not array\n";
}
?>

Output :

45 
7 

Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 262144 bytes) in ... on line 7

As per my knowledge, PHP will fall back to global function if a namespaced function does not exist.

Then why I am getting Fatal error here?

Also, is the fatal error I've received mean that the program is running into infinite loop? If yes, how? If no, what's the exact meaning of this fatal error?

  • All I see is that the "namespaced" function exists... – Kevin Kopf Jan 05 '18 at 19:38
  • 2
    *"fall back to global function if a namespaced function does not exist"* – well, but `strlen` *does* exist in your namespace, and it's an infinite recursive function. Of course the only thing it can do is run out of memory. – deceze Jan 05 '18 at 19:38
  • 1
    same as: `function myfunc($num) { return myfunc($num) - 1; }` use `return \strlen($str) - 1;` to have it call the PHP built-in. – AbraCadaver Jan 05 '18 at 19:41
  • 1
    @deceze I mean, honestly I would have expected it to overrun some sort of vertically oriented memory structure... :3c – Sammitch Jan 05 '18 at 21:17
  • @Sammitch Ah, like a *silo exhaust*? Yeah, same difference. – deceze Jan 05 '18 at 21:35

1 Answers1

1

Yes, the code you are using does run in an infinite loop. Here's how my test results look (a little more informative):

~ » php test.php
45
7
PHP Fatal error:  Maximum function nesting level of '256' reached, 
aborting! in /Users/xxx/test.php on line 5

If you are already overwriting std php function (which I would not recommend), you have to then explicitly run the std function by prefixing it with the backslash (use the global namespace).

<?php
namespace A\B\C;

const E_ERROR = 45;
function strlen($str)
{
    return \strlen($str) - 1;
}

echo E_ERROR, "\n"; // prints "45"
echo INI_ALL, "\n"; // prints "7" - falls back to global INI_ALL

echo strlen('hi'), "\n"; // prints "1"
if (is_array('hi')) { // prints "is not array"
    echo "is array\n";
} else {
    echo "is not array\n";
}

Results:

~ » php test.php
45
7
1
is not array

EDIT: Only now I've found this manual with a very similar example: http://php.net/manual/en/language.namespaces.global.php

Kwarcu
  • 141
  • 1
  • 4