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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: paul at namepros dot com
New email:
PHP Version: OS:

 

 [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

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Mon Dec 23 07:01:31 2024 UTC