php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #79675 Incorrect docs for array_key_exists opcode
Submitted: 2020-06-04 15:23 UTC Modified: 2020-06-04 15:59 UTC
From: paul at namepros dot com Assigned:
Status: Not a bug Package: Documentation problem
PHP Version: 7.4.6 OS: Linux 5.4.0
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
3 + 34 = ?
Subscribe to this entry?

 
 [2020-06-04 15:23 UTC] paul at namepros dot com
Description:
------------
---
From manual page: https://php.net/migration74.other-changes
---

On the aforementioned manual page, I read the following:

> A specialized VM opcode for the array_key_exists() function has been added, which improves performance of this function if it can be statically resolved. In namespaced code, this may require writing \array_key_exists() or explicitly importing the function.

This confirmed my assumption that `use array_key_exists;` should be a valid way to ensure that this new optimization is utilized in namespaced code.  However, I was surprised to find that it doesn't seem to work according to VLD.  Here's namespace-less code:

% php -dvld.active=1 -dvld.execute=0 -r 'array_key_exists(1, []);'
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       Command line code
function name:  (null)
number of ops:  3
compiled vars:  none
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
    1     0  E >   ARRAY_KEY_EXISTS                                 ~0      1, <array>
          1        FREE                                                     ~0
          2      > RETURN                                                   null

branch: #  0; line:     1-    1; sop:     0; eop:     2; out0:  -2
path #1: 0,

But here's what I get with a namespaced version with `use array_key_exists;`:

% php -dvld.active=1 -dvld.execute=0 -r 'namespace a; use array_key_exists; array_key_exists(1, []);'
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       Command line code
function name:  (null)
number of ops:  5
compiled vars:  none
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
    1     0  E >   INIT_NS_FCALL_BY_NAME                                    'a%5Carray_key_exists'
          1        SEND_VAL_EX                                              1
          2        SEND_VAL_EX                                              <array>
          3        DO_FCALL                                      0
          4      > RETURN                                                   null

branch: #  0; line:     1-    1; sop:     0; eop:     4; out0:  -2
path #1: 0,

Not what I expected, but https://www.php.net/manual/en/language.namespaces.faq.php#language.namespaces.faq.shortname2 seems to confirm that this is the expected behavior.  The only way to optimize function calls like `array_key_exists` and `is_array` in namespaced code appears to be to use the fully qualified name, e.g. `\array_key_exists`.

Test script:
---------------
<?php

namespace a;
use array_key_exists;

array_key_exists(1, []);


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-06-04 15:33 UTC] paul at namepros dot com
I attempted to fix the documentation myself, but https://edit.php.net/?project=PHP&perm=en/migration74.other-changes.php times out.
 [2020-06-04 15:59 UTC] nikic@php.net
-Status: Open +Status: Not a bug
 [2020-06-04 15:59 UTC] nikic@php.net
You are importing the array_key_exists class, not the array_key_exists function. You're looking for "use function array_key_exists".
 [2020-06-04 17:10 UTC] paul at namepros dot com
Ah, thanks; I knew I must be missing something.  I should've double-checked https://www.php.net/manual/en/language.namespaces.importing.php.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Sun Sep 27 18:01:26 2020 UTC