php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #49903 Strip $ at beginning of variable names for compact()
Submitted: 2009-10-16 15:25 UTC Modified: 2021-09-13 15:03 UTC
Votes:2
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: cschneid at cschneid dot com Assigned:
Status: Suspended Package: Arrays related
PHP Version: * OS: *
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: cschneid at cschneid dot com
New email:
PHP Version: OS:

 

 [2009-10-16 15:25 UTC] cschneid at cschneid dot com
Description:
------------
One reason we are not using compact() in our production code is that it is hard to search for variable references because $foo is simply called 'foo' in compact()

Suggestion: Strip off a leading $ before looking up variables, i.e. make compact('$foo') equivalent to compact('foo').

It's clear that people can shoot themselves in the foot if they try compact("$foo") but it would possibly make code using compact() a little easier to maintain.

Patch:
Index: ext/standard/array.c
===================================================================
--- ext/standard/array.c        (revision 289696)
+++ ext/standard/array.c        (working copy)
@@ -1488,7 +1488,7 @@
 {
        zstr key;
        int key_len;
-       zend_bool free_key = 0;
+       void *free_key = NULL;
        zval **value_ptr, *value, *data;

        if (Z_TYPE_P(entry) == IS_STRING || Z_TYPE_P(entry) == IS_UNICODE) {
@@ -1505,9 +1505,19 @@
                        } else if (norm != key.u) {
                                key.u = norm;
                                key_len = norm_len;
-                               free_key = 1;
+                               free_key = norm;
                        }
+                       if (*key.u == '$') {
+                               key.u++;
+                               key_len--;
+                       }
                }
+               else {
+                       if (*key.s == '$') {
+                               key.s++;
+                               key_len--;
+                       }
+               }
                if (zend_u_hash_find(eg_active_symbol_table, Z_TYPE_P(entry), key, key_len + 1, (void **)&value_ptr) != FAILURE) {
                        value = *value_ptr;
                        ALLOC_ZVAL(data);
@@ -1518,7 +1528,7 @@
                        zend_u_hash_update(Z_ARRVAL_P(return_value), Z_TYPE_P(entry), key, key_len + 1, &data, sizeof(zval *), NULL);
                }
                if (free_key) {
-                       efree(key.v);
+                       efree(free_key);
                }
        }
        else if (Z_TYPE_P(entry) == IS_ARRAY) {


Reproduce code:
---------------
sapi/cli/php -r '$foo = "FOO"; var_dump(compact("\$foo"));'

Expected result:
----------------
array(1) {
  [u"foo"]=>
  unicode(3) "FOO"
}


Actual result:
--------------
array(0) {
}


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-12-29 12:17 UTC] jani@php.net
-Package: Feature/Change Request +Package: Arrays related -Operating System: +Operating System: * -PHP Version: 6SVN-2009-10-16 (SVN) +PHP Version: *
 [2021-09-13 15:03 UTC] cmb@php.net
-Status: Open +Status: Suspended
 [2021-09-13 15:03 UTC] cmb@php.net
Well, that would be pretty uncommon for PHP (using variable names
elsewhere doesn't support a leading $ sign either).  Furthermore,
that wouldn't help you at all, since (emphasis mine):

> *One* reason we are not using compact() in our production code
> […]

Anyhow, I think this feature request requires the RFC process[1].
Feel free to start it any time; I suspend this ticket for the time
being.

[1] <https://wiki.php.net/rfc>
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Fri Mar 14 15:01:30 2025 UTC