I explore various questions pertaining to a medley of topics. Initially the talk focuses on some undocumented fun to be had with identifiers. Attention next shifts to PHP’s comma operator and considers whether it even merits that designation. The main topic, which follows, derives from an example of some very questionable PHP logic. To avoid making a hasty, superficial judgment will entail discovering the hidden story behind PHP’s truth values. Particularly fascinating is the influence of other languages on their development and meaning. This segment also peers into PHP’s internal workings in a friendly fashion for non-C programmers. Novices as well as senior developers are all welcome; there’s plenty of code for everyone! Come learn about what surprises await you.
2. Surprise! It's PHP
I. Introduction
II. What's in a Name?
III. The Mysterious
Comma
IV. Exploring Truth Values
V. Additional Thoughts
VI. Online Resources
3. Concluding someone … designed
PHP the way it is today. It has
history and heritage.
3
Common PHP Mistake
Flickr: by joanmaffeiart
Mike Wallner
See http://www.7php.com/php-interview-michael-wallner
8. A valid variable name starts
with a letter or underscore…
8
…..
See Manual: Basics
9. 9
I ♥ UTF-8
<?php
$♥ = "love";
echo "I $♥ PHP!";
// I love PHP!
See php_in_webapps.pdf; StackOverflow: unicode-identifiers-function-names…,
JDN Interview of Andi Gutmans June 2014
15. The Mysterious Comma
15
echo_expr_list:
<?php
echo $var1, $var2, …
See Manual: Operator Precedence
Left Associative
Many Uses
Has Least Precedence
16. The Mysterious Comma
16
echo_expr_list:
<?php
echo $var1, $var2, …
See PHP5.2 Changelog, lxr.php.net: echo_expr_list
17. 17
<?php
class Test {
const ALPHA = 1, BETA = 2, GAMMA = 3;
public $a = "apple", $b = "bread", $c = "candy";
// methods …
}
See StackOverflow: comma operator vs comma separator
30. … true, false, null … should be
all lower case, as upper case is
reserved for constants.
Coding Standards: FuelPHP
30
31. Constants should always be …
uppercase … This includes …PHP
constants … TRUE, FALSE and
NULL…
Coding Standards: Drupal
31
32. … PHP constants true, false,
and null MUST be in lower case.
32
Coding Standard: PSR-2
See php-FIG: PSR_2 and 8/2014 discussion: http://tinyurl.com/mdasjak
33. … in PHP, they are not constants;
they are keywords mapping to
language constructs.
Matthew Weir O'Phinney
Project Lead, Zend Framework, 2012
33
See Programming PHP by Rasmus Lerdorf, et al; Manual: define()
34. To specify a boolean literal, use
the keywords TRUE or FALSE.
34
See Bug report #67228
35. To specify a boolean literal, use
the constants TRUE or FALSE.
35
See Manual: Booleans
36. 36
Technically … count more as
reserved keywords than
constants…
Nikita Popov
See Stackoverflow: NickiC 2/7/2014
37. …case insensitive, to be
downwards compatible and
consistent with other languages…
Zeev Suraski
37
See Internals List: 5/8/98
39. Proof in the Pudding …
39
TRUE, FALSE, NULL
Usable as Identifiers
Ea. Has a Data Type
See Manual: Reserved Constants, Language: Constants, Zend API: Hacking the Core of PHP;
PHP Language Spec; 3v4l.org: V3H2n; Internals List: 7/16/2004
41. PERL Legacy
… truth value of expressions
in PHP is calculated in a
similar way to perl.
41
Zero
Zero
C false
JavaScript false
Perl false
PHP false
Python false
Ruby true
LISP true
Scheme true
False: 0
True: !0
False: "" and "0"
True : 1 [<,>,<=,=>,==]
PHP 3.0b4: lang-const.sgml
42. 42
PERL Legacy
False: 0
True: !0
Perl
False: "" and "0"
True : 1 [<,>,<=,=>,==]
See 3v4l.org: TrT4l; PerlMonks; What is true and false …
43. 43
PERL Legacy
Zero
Zero
C false
JavaScript false
Perl false
PHP false
Python false
Ruby true
LISP true
Scheme true
See StackOverflow: why-treat-0-as-true-in-ruby; is-false-0-and-true-1-in-python…
44. True/False as C Macros
44
#define TRUE 261
#define FALSE 262
45. True/False as Keywords
45
PHP3 Beta5 (2/98)
PHP_TRUE 1
PHP_FALSE ""
See Internals List 2/25/98 and bug report #354
47. True/False as Keywords
Made chown(), chgrp() and
chmod() return TRUE/FALSE
instead of 0/-1.
PHP 3.0b5 ChangeLog
47
PHP3 Beta5 (2/98)
See Internals List 2/25/98
48. 48
PHP3 Constant
name: true, false, …
name_len
value
value (pval)
value: [1, ""]
type: [IS_LONG, IS_STRING]
See Internals List 5/8/98, 7/1/98 ; PHP3 constants.[ch],
php.h; PHP3 Manual: Language constructs
49. Until PHP3rc5 …
$a = foo;
// Notice: 'foo' is not a valid constant[ PHP3rc5+ ]
// Notice: Use of undefined constant [ PHP4.3+ ]
$a = "foo"; // mandatory: quoted
49
See Internals List: 5/24/98; PHP3: language-parser.tab.c, line 2642
50. 50
Design & Consequences
if ("5") {
echo "Would print";
}
if ("5"==TRUE) {
echo "Would not print";
}
Zeev Suraski
General List: 7/1/98
See lang-const.html
51. 51
PHP4 Reinvention
zend_constant
See PHP 4: zend_constants.[ch], zend.h
value
value (zval)
value: [1, 0]
type: IS_BOOL
52. 52
PHP4 Reinvention
<?php
var_dump( (bool) 1);
// bool( true )
See Andi Gutmans commit 4/71999: zend_constants.c; Extending and Embedding PHP by Sara Golemon, p
165; Internals List: 6/4/2000
54. Improved Booleans
54
PHP5.6:
Z_LVAL_P(__z) = ((b) != 0);
Z_LVAL_P(__z) = IS_BOOL;
PHPNG:
Z_TYPE_INFO_P(z) = (b) ? IS_TRUE :
IS_FALSE;
See PHP5.6 and PHPNG: zend_constants.h, zend_constants.c, zend_API.h;
PHPNG: zend_types.h; also wiki.php.net: phpng; Internals List 11/10/2013
55. … I misunderstood the expression
evaluation of NULL/FALSE of PHP
for my entire PHP life
Yasuo Ohgaki
Internals List 11/10/2013
See blog.ohgaki.net: php-bool-null ( use Google translate); zend types.h: zval_bool and
zend_vm_execute.h: isset/empty handler
55
56. …please, don't make php
programmers go berserk :)
56
Michal Vitecek
See bug report: #4805
69. 69
<?php
$_POST[ "quantity" ] = "0";
if ( !empty( $_POST[ "quantity" ] ) ) {
echo "It's not empty"; // PHP 3
} else {
echo "It's empty"; // PHP 4
}
See Internals List 5/11/2000, Manual: empty PHP3 and PHP4; bug report #: 2088
70. 70
empty() considers "0" as
non-empty, a value that …
may come from an HTML
form.
See Internals List 5/11/2000, Manual: empty PHP3 and PHP4; bug report #: 2088
72. 72
Boolean "0"
Perl false
PHP false
C true
Python true
Ruby true
JavaScript true/false
See Manual: Booleans, bug report #39904, perlmonks.org: what is true and false in perl,
codepag.org: ScNhuOqY, 5zOu4NjN , Internals List: 2/25/98, 5/11/98, PHP3 ChangeLog: 5/11/98
73. 73
JavaScript's "0"
// JavaScript
if ("0") alert(""0" is true"); // true
if ("0" == false) alert(""0" is false"); // true
See StackOverflow: why-does-0-a-b-behave-different-than-0-true-a-b
74. "0" is no longer considered
false …
74
-
Zeev Suraski
See Internals List: 2/25/98, 5/11/98 and PHP3 ChangeLog: 5/11/98
75. 75
…we're still thinking whether
"0" should be considered false
Andi & Zeev
See Internals List: 2/25/98, 5/11/98 and PHP3 ChangeLog: 5/11/98
76. "" (string,false) <=> 0 (int, false) <=> "0"(string,true)
76
See Internals List: 2/25/98, 5/11/98 and PHP3 ChangeLog: 5/11/98
77. ***NOTE*** Changed "0" to
mean FALSE again
77
See Internals List: 2/25/98, 5/11/98 and PHP3 ChangeLog: 5/11/98
81. 81
Counts all elements in an
array, or something in an
object
PHP5 Manual
See lxr.php.net: array.c, Bug reports #: 46322 and #: 60577
82. Returns the number of elements
in var, … typically an array …
anything else will have one
element ...
82
PHP3 Manual
See lxr.php.net: array.c, Bug reports #: 46322 and #: 60577
83. 83
switch (Z_TYPE_P(array)) {
case IS_NULL:
RETURN_LONG(0);
break;
case IS_ARRAY: [snipped]
case IS_OBJECT:
/* handler defined? */
/* If Countable, call count() method */
default:
RETURN_LONG(1);
break;
}
See lxr.php.net: array.c, Bug reports #: 46322 and #: 60577
85. Dec 28, 1999 (Thies Arntzen) new constant SQL_NULL
PHP4.0b4: (Feb 2000)
Added new NULL constant (Zeev, Zend Engine)
85
About Null
c.value.value.lval = 0;
c.value.type = IS_LONG;
See Thies Arntzen's Commit, PHP4 Changelog; PHP 4: zend_constants.c; bug report: #67562
86. 86
About NULL
zend_constant
value
value (zval)
vvaalluuee:: [[ uunnsseett ]]
ttyyppee:: IISS__NNUULLLL
null is not a value, was never
meant to be a value, and won't
be a value.
Zeev Suraski
Internals List 8/17/2003
See PHP4.0b4 Changelog; PHP 4: zend_constants.c; bug report: #67562
87. 87
<?php
echo (int) null;
// 0
See lxr.php.net: (PHP5.2) zend_operators.c annotated and history.
88. 88
// Dec. 31, 1999 – introduced IS_UNSET - Zeev Suraski
convert_to_long_base( zval *op, int base ):
switch (op->type) {
case IS_UNSET:
op->value.lval = 0;
break;
See lxr.php.net: (PHP5.2) zend_operators.c annotated and history.
89. 89
// Jan 4, 2000: IS_UNSET => IS_NULL - Andi Gutmans
convert_to_long_base( zval *op, int base ):
switch (op->type) {
case IS_NULL:
op->value.lval = 0;
break;
See lxr.php.net: (PHP5.2) zend_operators.c annotated and history.
99. 99
// int increment_function
case IS_BOOL:
op1->value.lval++;
op1->type = IS_LONG;
break;
case IS_NULL:
op1->value.lval = 1;
op1->type.lval = IS_LONG;
// int decrement_function
case IS_BOOL:
op1->value.lval--;
op1->type = IS_LONG;
break;
case IS_NULL:
op1->value.lval = -1;
op1->type = IS_LONG;
Excerpted from Johannes Schlueter's Patch; see also Tjerk Meesters'
RFC:Normalize increment and decrement operators
100. 100
// JavaScript:
var m = null, n = null;
alert( ++m ); // 1
alert( --n ); // -1
var e = true, f = false;
alert( ++e ); // 2
alert( --f ); // -1
101. 101
<?php
// * Sum byte values from position x in $str
function sum( $str, $x ) {
$sum = 0;
for ( $max = strlen( $str );
$x < $max;
++$x ) {
$sum += ord( $str[ $x ] );
}
return $sum;
}
$str = 'Hello, Dolly';
echo sum( $str, strpos( $str, 'F' ) ); // typo: sh/b 'D'
See Internals List 6/5/2005, Johannes Schlueter's Patch and Tjerk
Meesters' RFC: Normalize increment and decrement operators
102. Compare NULL & Any
102
Convert both sides to bool
FALSE < TRUE
See Internals List 11/10/2013; Manual: comparison operators: PHP5.3 and PHP5.5
103. Compare NULL & Any
103
<?php
echo null < -1;
echo false < true;
See Internals List 11/10/2013; Manual: comparison operators: PHP5.3 and PHP5.5
Talk explores basic notions in PHP fr holistic perspective
Who knows what surprises we may encounter …
Benefit: help avoid making common PHP mistake
PHPland – an idllyic place?
Maybe …
Early adoptees shared Lerdorf&apos;s enthusiasm
Like Rasmus we knew C, Perl and JAVA -- all langs impacting PHP&apos;s design
Today&apos;s programmer: Has s/he heard of Perl, let alone know it?
Ignorance of languages impacting PHP may result =&gt; metaphor about PHP and vacuum cleaner.
Early adoptees shared Lerdorf&apos;s enthusiasm
Like Rasmus we knew C, Perl and JAVA -- all langs impacting PHP&apos;s design
Today&apos;s programmer: Has s/he heard of Perl, let alone know it?
Ignorance of languages impacting PHP may result =&gt; metaphor about PHP and vacuum cleaner.
Early part of this year someone alleged on Internals List: a hole in PHP&apos;s design!
Response to a discussion about bizarre PHP identifiers
Definition fr Manual
Begs question: what consittitues a letter ...
Code more than decorative – executable!
When did PHP start supporting Unicode?
PHP does not natively support unicode nor will it per A Gutmans
Standard String library funcs unaware of multibyte chars
PHP does not natively support unicode nor willl it per A Gutmans!
Heart symbol when utf8-encoded (default) composed of multiple bytes whose hex values all coincidentally
fall within acceptable range [a-zA-Z0-9] and ascii(128-255) of numerical values for bytes.
Can use multibyte string (aka mbstring) ext. (recc&apos;d by Drupal) to disallow unicode char or rather code point.
Code more than decorative – executable!
When did PHP start supporting Unicode?
PHP does not natively support unicode nor will it per A Gutmans
Standard String library funcs unaware of multibyte chars
PHP does not natively support unicode nor willl it per A Gutmans!
Heart symbol when utf8-encoded (default) composed of multiple bytes whose hex values all coincidentally
fall within acceptable range [a-zA-Z0-9] and ascii(128-255) of numerical values for bytes.
Can use multibyte string (aka mbstring) ext. (recc&apos;d by Drupal) to disallow unicode char or rather code point.
Code more than decorative – executable!
When did PHP start supporting Unicode?
PHP does not natively support unicode nor will it per A Gutmans
Standard String library funcs unaware of multibyte chars
PHP does not natively support unicode nor willl it per A Gutmans!
Heart symbol when utf8-encoded (default) composed of multiple bytes whose hex values all coincidentally
fall within acceptable range [a-zA-Z0-9] and ascii(128-255) of numerical values for bytes.
Can use multibyte string (aka mbstring) ext. (recc&apos;d by Drupal) to disallow unicode char or rather code point.
Code more than decorative – executable!
When did PHP start supporting Unicode?
PHP does not natively support unicode nor will it per A Gutmans
Standard String library funcs unaware of multibyte chars
PHP does not natively support unicode nor willl it per A Gutmans!
Heart symbol when utf8-encoded (default) composed of multiple bytes whose hex values all coincidentally
fall within acceptable range [a-zA-Z0-9] and ascii(128-255) of numerical values for bytes.
Can use multibyte string (aka mbstring) ext. (recc&apos;d by Drupal) to disallow unicode char or rather code point.
Is there a hole in PHP&apos;s design? Debatable.
Per Lerdorf: No b/c in early days focus on not arbitrarily limiting identifiers.
Any char conflicting with PHP disallowed. Think &lt;space&gt; ; , { } ( ) etc.
Speaking of the comma …
Ubiquitous so-called operator
How well do we really understand it?
In C, comma has least precedence as an op
PHP inherits its syntax from C
In PHP more of a separator: used for lists and declarations:
Example - echo_list: echo $var1, $var2, …
In C, comma has least precedence as an op
PHP inherits its syntax from C
In PHP more of a separator: used for lists and declarations:
Example - echo_list: echo $var1, $var2, …
Comma as separator specifies:
&quot;c&quot;-type constants declared as are class properties
(a declaration specifies type and identifier to inform compiler about element)
Parse error msg: unexpected &apos;,&apos;
Comma as separator specifies:
&quot;c&quot;-type constants declared as are class properties
(a declaration specifies type and identifier to inform compiler about element)
Parse error msg: unexpected &apos;,&apos;
Comma as separator specifies:
&quot;c&quot;-type constants declared as are class properties
(a declaration specifies type and identifier to inform compiler about element)
Parse error msg: unexpected &apos;,&apos;
Does PHP belong?
The other langs support a binary comma operator
JS example …
processes 1st op, discards it, but side-effect (incremented var) captured and used in 2nd expr which evaluates and its result is usable
and gets assigned to x.
Try in your browser: javascript: if (a=1,b=2) alert(a+b);
Same day requested, prompty rejected
Smart decision or too conservative?
Binary comma best in for-loops according to some authorities
for(initialization; condition; iteration_expression)
Best for initialization expression altho&apos; may be used for multiple operations, too.
Binary comma best in for-loops according to some authorities
for(initialization; condition; iteration_expression)
Best for initialization expression altho&apos; may be used for multiple operations, too.
PHP&apos;s logic stands on a slippery slope per its detractors
Use cases?
Eevee in his infamous rant remarks that first comparison is inconsistent with the 2nd.
To make matters worse,
JavaScript does things opposite of PHP.
How JS does it …
Who&apos;s got it rt and who&apos;s got it wrong?
It&apos;s really about different design approaches.
Essential question: How well do we understand the truth values and null in PHP?
T/F/N: keywords or constants?
Does it matter? Yes b/c that perception determines:
How we express them
Availability of identifiers
PSR-2 from PHP Framework Interop[erability] Group (FIG)
[Proposing a Standards Recommendation (PSR)]
Contacted Phil Sturgeon, prominent FIG member.
He explained: Some saw constants, others felt they were more like keywords,
Standard result of vote and Not going to change!
Never say never : think case of pow operator and Jim Winstead.
Per Sturgeon&apos;s suggestion I discuss further on php-FIG. After a flurry of emails (19) exchanged, the next day David Grudl forked php-FIG and created php-fg which has its own PGS-2: T&F Constants;upper or lowercase fine. A joke? But then every joke may be ½ serious …
MWOP take
How does such a misunderstanding arise ?
Maybe b/c of one book: Programming PHP by Father of PHP himself, Rasmus Lerdor et al
Not one erratum despite 3 eds in re TRUE/FALSE designated as keywords
Arg for lowercasing:
PHP API var_dump,var_export follows ZE
Retort: funcs result do what code would do if constants accessed, such that the ZE would return lowercased forms
– all CI constants stored in lowercase.
Orginally all constants were lowercased (see PHP3) but at some pt decision to only lowercase CI constants.
Uppercase convenience for user eyes whereas lowercasing TRUE, FALSE and NULL for hashtable storage may be related to processing or may even be an arbitrary decision with no distinct advantage.
While they may seem like keywords use kw as identifiers (except for variables b/c $ let&apos;s us get alway with that)
http://3v4l.org/V3H2n, but with constants we may!
====================================================
Option: could add them back as keywords and deprecate and remove the alternate syntax:endfor,endswitch,endif,endforeach (and their has been discussion on Internals List recently about deprecating such keywords and then removing them.
T/F/N: keywords or constants?
Does it matter? Yes b/c that perception determines:
How we express them
Availability of identifiers
PSR-2 from PHP Framework Interop[erability] Group (FIG)
[Proposing a Standards Recommendation (PSR)]
Contacted Phil Sturgeon, prominent FIG member.
He explained: Some saw constants, others felt they were more like keywords,
Standard result of vote and Not going to change!
Never say never : think case of pow operator and Jim Winstead.
Per Sturgeon&apos;s suggestion I discuss further on php-FIG. After a flurry of emails (19) exchanged, the next day David Grudl forked php-FIG and created php-fg which has its own PGS-2: T&F Constants;upper or lowercase fine. A joke? But then every joke may be ½ serious …
MWOP take
How does such a misunderstanding arise ?
Maybe b/c of one book: Programming PHP by Father of PHP himself, Rasmus Lerdor et al
Not one erratum despite 3 eds in re TRUE/FALSE designated as keywords
Arg for lowercasing:
PHP API var_dump,var_export follows ZE
Retort: funcs result do what code would do if constants accessed, such that the ZE would return lowercased forms
– all CI constants stored in lowercase.
Orginally all constants were lowercased (see PHP3) but at some pt decision to only lowercase CI constants.
Uppercase convenience for user eyes whereas lowercasing TRUE, FALSE and NULL for hashtable storage may be related to processing or may even be an arbitrary decision with no distinct advantage.
While they may seem like keywords use kw as identifiers (except for variables b/c $ let&apos;s us get alway with that)
http://3v4l.org/V3H2n, but with constants we may!
====================================================
Option: could add them back as keywords and deprecate and remove the alternate syntax:endfor,endswitch,endif,endforeach (and their has been discussion on Internals List recently about deprecating such keywords and then removing them.
T/F/N: keywords or constants?
Does it matter? Yes b/c that perception determines:
How we express them
Availability of identifiers
PSR-2 from PHP Framework Interop[erability] Group (FIG)
[Proposing a Standards Recommendation (PSR)]
Contacted Phil Sturgeon, prominent FIG member.
He explained: Some saw constants, others felt they were more like keywords,
Standard result of vote and Not going to change!
Never say never : think case of pow operator and Jim Winstead.
Per Sturgeon&apos;s suggestion I discuss further on php-FIG. After a flurry of emails (19) exchanged, the next day David Grudl forked php-FIG and created php-fg which has its own PGS-2: T&F Constants;upper or lowercase fine. A joke? But then every joke may be ½ serious …
MWOP take
How does such a misunderstanding arise ?
Maybe b/c of one book: Programming PHP by Father of PHP himself, Rasmus Lerdor et al
Not one erratum despite 3 eds in re TRUE/FALSE designated as keywords
Arg for lowercasing:
PHP API var_dump,var_export follows ZE
Retort: funcs result do what code would do if constants accessed, such that the ZE would return lowercased forms
– all CI constants stored in lowercase.
Orginally all constants were lowercased (see PHP3) but at some pt decision to only lowercase CI constants.
Uppercase convenience for user eyes whereas lowercasing TRUE, FALSE and NULL for hashtable storage may be related to processing or may even be an arbitrary decision with no distinct advantage.
While they may seem like keywords use kw as identifiers (except for variables b/c $ let&apos;s us get alway with that)
http://3v4l.org/V3H2n, but with constants we may!
====================================================
Option: could add them back as keywords and deprecate and remove the alternate syntax:endfor,endswitch,endif,endforeach (and their has been discussion on Internals List recently about deprecating such keywords and then removing them.
T/F/N: keywords or constants?
Does it matter? Yes b/c that perception determines:
How we express them
Availability of identifiers
PSR-2 from PHP Framework Interop[erability] Group (FIG)
[Proposing a Standards Recommendation (PSR)]
Contacted Phil Sturgeon, prominent FIG member.
He explained: Some saw constants, others felt they were more like keywords,
Standard result of vote and Not going to change!
Never say never : think case of pow operator and Jim Winstead.
Per Sturgeon&apos;s suggestion I discuss further on php-FIG. After a flurry of emails (19) exchanged, the next day David Grudl forked php-FIG and created php-fg which has its own PGS-2: T&F Constants;upper or lowercase fine. A joke? But then every joke may be ½ serious …
MWOP take
How does such a misunderstanding arise ?
Maybe b/c of one book: Programming PHP by Father of PHP himself, Rasmus Lerdor et al
Not one erratum despite 3 eds in re TRUE/FALSE designated as keywords
Arg for lowercasing:
PHP API var_dump,var_export follows ZE
Retort: funcs result do what code would do if constants accessed, such that the ZE would return lowercased forms
– all CI constants stored in lowercase.
Orginally all constants were lowercased (see PHP3) but at some pt decision to only lowercase CI constants.
Uppercase convenience for user eyes whereas lowercasing TRUE, FALSE and NULL for hashtable storage may be related to processing or may even be an arbitrary decision with no distinct advantage.
While they may seem like keywords use kw as identifiers (except for variables b/c $ let&apos;s us get alway with that)
http://3v4l.org/V3H2n, but with constants we may!
====================================================
Option: could add them back as keywords and deprecate and remove the alternate syntax:endfor,endswitch,endif,endforeach (and their has been discussion on Internals List recently about deprecating such keywords and then removing them.
T/F/N: keywords or constants?
Does it matter? Yes b/c that perception determines:
How we express them
Availability of identifiers
PSR-2 from PHP Framework Interop[erability] Group (FIG)
[Proposing a Standards Recommendation (PSR)]
Contacted Phil Sturgeon, prominent FIG member.
He explained: Some saw constants, others felt they were more like keywords,
Standard result of vote and Not going to change!
Never say never : think case of pow operator and Jim Winstead.
Per Sturgeon&apos;s suggestion I discuss further on php-FIG. After a flurry of emails (19) exchanged, the next day David Grudl forked php-FIG and created php-fg which has its own PGS-2: T&F Constants;upper or lowercase fine. A joke? But then every joke may be ½ serious …
MWOP take
How does such a misunderstanding arise ?
Maybe b/c of one book: Programming PHP by Father of PHP himself, Rasmus Lerdor et al
Not one erratum despite 3 eds in re TRUE/FALSE designated as keywords
Arg for lowercasing:
PHP API var_dump,var_export follows ZE
Retort: funcs result do what code would do if constants accessed, such that the ZE would return lowercased forms
– all CI constants stored in lowercase.
Orginally all constants were lowercased (see PHP3) but at some pt decision to only lowercase CI constants.
Uppercase convenience for user eyes whereas lowercasing TRUE, FALSE and NULL for hashtable storage may be related to processing or may even be an arbitrary decision with no distinct advantage.
While they may seem like keywords use kw as identifiers (except for variables b/c $ let&apos;s us get alway with that)
http://3v4l.org/V3H2n, but with constants we may!
====================================================
Option: could add them back as keywords and deprecate and remove the alternate syntax:endfor,endswitch,endif,endforeach (and their has been discussion on Internals List recently about deprecating such keywords and then removing them.
Truth: We&apos;ve also been misled by Manual.
Consider source code going back to even before official release of PHP3
So, I filed a bug report; docs have now been fixed to reflect the truth.
Nitkita&apos;s thoughts …
The constants seem more like keywords semantically, e.g. True == true, like &quot;echo&quot; merely returns T_ECHO as echo means echo.
When originally appeared in PHP3 perceived officially as constants; Zeev Suraski who created them as CI (BC compatible and consistent w/other languages) urged that they be uppercased.
Truth: We&apos;ve also been misled by Manual.
Consider source code going back to even before official release of PHP3
So, I filed a bug report; docs have now been fixed to reflect the truth.
Nitkita&apos;s thoughts …
The constants seem more like keywords semantically, e.g. True == true, like &quot;echo&quot; merely returns T_ECHO as echo means echo.
When originally appeared in PHP3 perceived officially as constants; Zeev Suraski who created them as CI (BC compatible and consistent w/other languages) urged that they be uppercased.
Truth: We&apos;ve also been misled by Manual.
Consider source code going back to even before official release of PHP3
So, I filed a bug report; docs have now been fixed to reflect the truth.
Nitkita&apos;s thoughts …
The constants seem more like keywords semantically, e.g. True == true, like &quot;echo&quot; merely returns T_ECHO as echo means echo.
When originally appeared in PHP3 perceived officially as constants; Zeev Suraski who created them as CI (BC compatible and consistent w/other languages) urged that they be uppercased.
Truth: We&apos;ve also been misled by Manual.
Consider source code going back to even before official release of PHP3
So, I filed a bug report; docs have now been fixed to reflect the truth.
Nitkita&apos;s thoughts …
The constants seem more like keywords semantically, e.g. True == true, like &quot;echo&quot; merely returns T_ECHO as echo means echo.
When originally appeared in PHP3 perceived officially as constants; Zeev Suraski who created them as CI (BC compatible and consistent w/other languages) urged that they be uppercased.
http://php.net/manual/en/reserved.constants.php:
TRUE
FALSE
NULL
http://php.net/manual/en/language.constants.php:
&quot;By convention, constant identifiers are always uppercase.&quot;
PHP4 and ZE1: boolean constants; Manual calls them &quot;true constants&quot;. As oppposed to what? Variables!
They are actually:
Static read-only variables
Stored in hashtable, globally accessible
CI unlike other constants for sake of BC and consistency w/other langs (Zeev)
Don&apos;t need and shouldn&apos;t use $ to use them
PHP Lang Spec (courtesy FB,SG) confirms they are constants.
This issue should not be ambiguous, but rather straightforward and very clear.
the booleans sure seem like keywords so could add them back as keywords and deprecate and remove the alternate syntax: endfor,endswitch,endif,endforeach
http://php.net/manual/en/reserved.constants.php:
TRUE
FALSE
NULL
http://php.net/manual/en/language.constants.php:
&quot;By convention, constant identifiers are always uppercase.&quot;
PHP4 and ZE1: boolean constants; Manual calls them &quot;true constants&quot;. As oppposed to what? Variables!
They are actually:
Static read-only variables
Stored in hashtable, globally accessible
CI unlike other constants for sake of BC and consistency w/other langs (Zeev)
Don&apos;t need and shouldn&apos;t use $ to use them
PHP Lang Spec (courtesy FB,SG) confirms they are constants.
This issue should not be ambiguous, but rather straightforward and very clear.
the booleans sure seem like keywords so could add them back as keywords and deprecate and remove the alternate syntax: endfor,endswitch,endif,endforeach
Determining TRUE and FALSE …
Statement from early version version pre-release of PHP3
Expr == 0, false
else !0 == true in PHP;
Initially no explicit way to handle true,false
What Perl does:
Defines false, then derives true, so neg numbers are true, too!
[Ruby: only false and null are false; if exists then true
LISP: only Nil (empty list) is false;
Scheme #f is false]
Boolean 0 value matter of convention.
[Scheme: dialect of LISP; see http://c2.com/cgi/wiki?LispSchemeDifferences]
Determining TRUE and FALSE …
Statement from early version version pre-release of PHP3
Expr == 0, false
else !0 == true in PHP;
Initially no explicit way to handle true,false
What Perl does:
Defines false, then derives true, so neg numbers are true, too!
[Ruby: only false and null are false; if exists then true
LISP: only Nil (empty list) is false;
Scheme #f is false]
Boolean 0 value matter of convention.
[Scheme: dialect of LISP; see http://c2.com/cgi/wiki?LispSchemeDifferences]
Determining TRUE and FALSE …
Statement from early version version pre-release of PHP3
Expr == 0, false
else !0 == true in PHP;
Initially no explicit way to handle true,false
What Perl does:
Defines false, then derives true, so neg numbers are true, too!
[Ruby: only false and null are false; if exists then true
LISP: only Nil (empty list) is false;
Scheme #f is false]
Boolean 0 value matter of convention.
[Scheme: dialect of LISP; see http://c2.com/cgi/wiki?LispSchemeDifferences]
Determining TRUE and FALSE …
Statement from early version version pre-release of PHP3
Expr == 0, false
else !0 == true in PHP;
Initially no explicit way to handle true,false
What Perl does:
Defines false, then derives true, so neg numbers are true, too!
[Ruby: only false and null are false; if exists then true
LISP: only Nil (empty list) is false;
Scheme #f is false]
Boolean 0 value matter of convention.
[Scheme: dialect of LISP; see http://c2.com/cgi/wiki?LispSchemeDifferences]
Macro definition,substitution similar to PHP constant; K&R: symbolic constants
In Perl and JS &quot;&quot; means false in boolean context
Big benefit: now functions could return true and false instead of 0 & -1 as PHP/FI.
Seems incongruous 1 and &quot;&quot; but exemplifies PHP pragmatism
Reason: Internally, follows Perl which returns &quot;&quot; for when false (internally 0) is in string context
Macro definition,substitution similar to PHP constant; K&R: symbolic constants
In Perl and JS &quot;&quot; means false in boolean context
Big benefit: now functions could return true and false instead of 0 & -1 as PHP/FI.
Seems incongruous 1 and &quot;&quot; but exemplifies PHP pragmatism
Reason: Internally, follows Perl which returns &quot;&quot; for when false (internally 0) is in string context
Macro definition,substitution similar to PHP constant; K&R: symbolic constants
In Perl and JS &quot;&quot; means false in boolean context
Big benefit: now functions could return true and false instead of 0 & -1 as PHP/FI.
Seems incongruous 1 and &quot;&quot; but exemplifies PHP pragmatism
Reason: Internally, follows Perl which returns &quot;&quot; for when false (internally 0) is in string context
Macro definition,substitution similar to PHP constant; K&R: symbolic constants
In Perl and JS &quot;&quot; means false in boolean context
Big benefit: now functions could return true and false instead of 0 & -1 as PHP/FI.
Seems incongruous 1 and &quot;&quot; but exemplifies PHP pragmatism
Reason: Internally, follows Perl which returns &quot;&quot; for when false (internally 0) is in string context
May 8 &apos;98:
Zeev Suraski figured out how to implement constants in PHP
Changed true and false from keywords to constants backwards compatible and with a usage like other languages.
True and false among first constants he created, too.
True and false as keywords eliminated – one of the design goals of PHP is to minimize keywords.
See constants.h for php3_constant:
PHP.h:
typedef struct _pval_struct pval;
struct _pval_struct
typedef union yystype_value;
PHP3: (6/98)
Undocumented feature now impeded by new constants feature, ergo notice.
Undocumented feature now impeded by new constants feature, ergo notice.
Not Boolean Constants!
1st – example of truth-expression context
2nd would be superfluous if only TRUE was really a boolean instead:
2nd &quot;5&quot; == 1 (NO!)
&quot;…PHP doesn&apos;t have a dedicated boolean type …&quot; (PHP3 Manual)
http://lxr.php.net/xref/PHP_5_2/Zend/zend_constants.c?a=true&r=573b46022c46ab41a879c23f4ea432dd4d0c102e:
Andi Gutmans commited true and false as boolean constants 4/7/99, as part of the new Zend engine.
PHP4: 5/2000 –
PHP projects&apos; greatest strength: willingness to change. That kind of flexibility has contributed to its longevity.
zend_register_constant(): lowercased name stored in HashTable
Booleans arrive: may 2000 per http://en.wikipedia.org/wiki/PHP
http://lxr.php.net/xref/PHP_5_2/Zend/zend_constants.c?a=true&r=573b46022c46ab41a879c23f4ea432dd4d0c102e:
Andi Gutmans commited true and false as boolean constants 4/7/99, as part of the new Zend engine.
PHP4: 5/2000 –
PHP projects&apos; greatest strength: willingness to change. That kind of flexibility has contributed to its longevity.
zend_register_constant(): lowercased name stored in HashTable
Booleans arrive: may 2000 per http://en.wikipedia.org/wiki/PHP
Marcus Boerger (SPL) sought to optimize PHP in 2004 PHP5.1 by eliminating FETCH_CONSTANT opcode generating for accessing true,false and null
He modified zend_language_scanner.l and zend_language_parser.y to re-implement as keywords true,false and null and thereby eliminate opcode. (7/16/2004; [see http://lxr.php.net/xref/PHP_5_3/Zend/zend_language_scanner.l?r=86d46f7cc10adbdef89968cde921bb6e975feeb7#1307;
also see http://lxr.php.net/xref/PHP_5_3/Zend/zend_language_parser.y?r=86d46f7cc10adbdef89968cde921bb6e975feeb7#145 – for the tokens (7/16/2004)]
And: 8/2/2004 reverted – after &lt; 3wks, i.e. 2wk & 4 days)
Sterling Hughes forced Boerger&apos;s to revert patch b/c &quot;…the performance increase is neglible - its a *bad* optimization. &quot; (see http://markmail.org/message/w66pun34oxnmxo6c)
[http://lxr.php.net/history/PHP_5_2/Zend/zend_language_scanner.l (History: Marcus Boerger: 8/2/2004 reverted everything but noted # - NULL can be reintroduced later when needed
Andi G had been in favor of turning T/F/N into keywords (see http://markmail.org/message/q6wfe2cm465ofd6o).
Today&apos;s code is similar to PHP3 and PHP4 but makes more clear that the fundamental meaning of 0 is False and not the other way around (which a core contributor confessed he had mis-aprehended fundamental meaning of TRUE and FALSE for &quot;…my entire PHP life…&quot;.
Thought that fundamentally FALSE means 0 and not the other way around.
The consternation surrounding display of FALSE …
PHP: boolean not;
C: logical negation
! Creates boolean context and reverses boolean value, ie true-&gt;false and false-&gt;true
! : convert operand to Boolean:
PHP3 0/1; expressions (0) == false and (1) == true in Perl, C and PHP3
Type s/b long_int
PHP4 0/1 IS_BOOL
Then apply logical negation so true-&gt;false and false-&gt;true
False in string context &quot;&quot; but &quot;0&quot; == false
Follows Perl – all unset vars have value of &quot;&quot; in string context; awkward to use &quot;0&quot;
So, we see nothing b/c PHP prints empty string? No! PHP prints nothing in case of false
PHP: boolean not;
C: logical negation
! Creates boolean context and reverses boolean value, ie true-&gt;false and false-&gt;true
! : convert operand to Boolean:
PHP3 0/1; expressions (0) == false and (1) == true in Perl, C and PHP3
Type s/b long_int
PHP4 0/1 IS_BOOL
Then apply logical negation so true-&gt;false and false-&gt;true
False in string context &quot;&quot; but &quot;0&quot; == false
Follows Perl – all unset vars have value of &quot;&quot; in string context; awkward to use &quot;0&quot;
So, we see nothing b/c PHP prints empty string? No! PHP prints nothing in case of false
PHP: boolean not;
C: logical negation
! Creates boolean context and reverses boolean value, ie true-&gt;false and false-&gt;true
! : convert operand to Boolean:
PHP3 0/1; expressions (0) == false and (1) == true in Perl, C and PHP3
Type s/b long_int
PHP4 0/1 IS_BOOL
Then apply logical negation so true-&gt;false and false-&gt;true
False in string context &quot;&quot; but &quot;0&quot; == false
Follows Perl – all unset vars have value of &quot;&quot; in string context; awkward to use &quot;0&quot;
So, we see nothing b/c PHP prints empty string? No! PHP prints nothing in case of false
Cascade of function calls:
ECHO opcode -&gt; ZEND_ECHO_SPEC_CONST_HANDLER -&gt;zend_print_variable()-&gt;zend_print_zval-&gt;zend_print_zval_ex-&gt;
False in string context &quot;&quot; but &quot;0&quot; == false
Follows Perl – all unset vars have value of &quot;&quot; in string context; awkward to use &quot;0&quot;
So, we see nothing b/c PHP prints empty string? No! PHP prints nothing in case of false
write_func() only display strings that are non-empty.
Cascade of function calls:
ECHO opcode -&gt; ZEND_ECHO_SPEC_CONST_HANDLER -&gt;zend_print_variable()-&gt;zend_print_zval-&gt;zend_print_zval_ex-&gt;
False in string context &quot;&quot; but &quot;0&quot; == false
Follows Perl – all unset vars have value of &quot;&quot; in string context; awkward to use &quot;0&quot;
So, we see nothing b/c PHP prints empty string? No! PHP prints nothing in case of false
write_func() only display strings that are non-empty.
Cascade of function calls:
ECHO opcode -&gt; ZEND_ECHO_SPEC_CONST_HANDLER -&gt;zend_print_variable()-&gt;zend_print_zval-&gt;zend_print_zval_ex-&gt;
False in string context &quot;&quot; but &quot;0&quot; == false
Follows Perl – all unset vars have value of &quot;&quot; in string context; awkward to use &quot;0&quot;
So, we see nothing b/c PHP prints empty string? No! PHP prints nothing in case of false
write_func() only display strings that are non-empty.
Is Father of PHP right?
Manual explains allows conversion back and forth between boolean and string vals. (automatic and via casting).
echo((bool)&quot;&quot;); can convert to false and then to &quot;&quot; but &quot;0&quot; =&gt; false nad then (string) false == &quot;0&quot;
&quot;&quot; =&gt; false =&gt; &quot;&quot;
&quot;0&quot; =&gt; false =&gt; &quot;0&quot;
echo ( (bool) null);
Is Father of PHP right?
Manual explains allows conversion back and forth between boolean and string vals. (automatic and via casting).
echo((bool)&quot;&quot;); can convert to false and then to &quot;&quot; but &quot;0&quot; =&gt; false nad then (string) false == &quot;0&quot;
&quot;&quot; =&gt; false =&gt; &quot;&quot;
&quot;0&quot; =&gt; false =&gt; &quot;0&quot;
echo ( (bool) null);
Is Father of PHP right?
Manual explains allows conversion back and forth between boolean and string vals. (automatic and via casting).
echo((bool)&quot;&quot;); can convert to false and then to &quot;&quot; but &quot;0&quot; =&gt; false nad then (string) false == &quot;0&quot;
&quot;&quot; =&gt; false =&gt; &quot;&quot;
&quot;0&quot; =&gt; false =&gt; &quot;0&quot;
echo ( (bool) null);
Mirky issues …
Null expr statement in for loop defaults to true in C, PHP.
Per PHP3.0b4: Lang-syntax.sgml: &quot;PHP&apos;s syntax is borrowed primarily from C. Java and Perl have also influenced the syntax. &quot;
language-const.sgml: &quot;The truth value of expressions in PHP is calculated in a similar way to perl. Any numeric non-zero numeric value is TRUE, zero is FALSE. … &quot;
&quot;FOR … behave like their C counterparts. … Each of the expressions can be empty. expr2 being empty means the loop should be run indefinitely (PHP implicitly considers it as TRUE, like C). &quot;
Null expr statement in for loop defaults to true in C, PHP.
Per PHP3.0b4: Lang-syntax.sgml: &quot;PHP&apos;s syntax is borrowed primarily from C. Java and Perl have also influenced the syntax. &quot;
language-const.sgml: &quot;The truth value of expressions in PHP is calculated in a similar way to perl. Any numeric non-zero numeric value is TRUE, zero is FALSE. … &quot;
&quot;FOR … behave like their C counterparts. … Each of the expressions can be empty. expr2 being empty means the loop should be run indefinitely (PHP implicitly considers it as TRUE, like C). &quot;
Alphanumeric string and per PHP3 manual:
&apos;empty() considers &quot;0&quot; as non-empty, a value that for example may come from an HTML form.&apos; (see http://php.net/manual/php3.php)
PHP4: &apos;0&apos; == 0, so empty() is true! (see https://bugs.php.net/bug.php?id=2088);
Remedy: use isset() instead of empty() if &quot;0&quot; is valid input
But PHP manual 3-&gt;4: most controversial change empty(&quot;0&quot;) true!
Alphanumeric string and per PHP3 manual:
&apos;empty() considers &quot;0&quot; as non-empty, a value that for example may come from an HTML form.&apos; (see http://php.net/manual/php3.php)
PHP4: &apos;0&apos; == 0, so empty() is true! (see https://bugs.php.net/bug.php?id=2088);
Remedy: use isset() instead of empty() if &quot;0&quot; is valid input
But PHP manual 3-&gt;4: most controversial change empty(&quot;0&quot;) true!
Empty str in PHP really is empty b/c PHP strings don&apos;t have to be null-terminated.
&quot; &quot; == true follows Perl and C which view string with one character.
But &quot;0&quot; has one character – special exception so PHP follows Perl and renders it as false
http://codepad.org/oWltWsa1 (Python &quot;0&quot; alphanumeric string evals as true.
PHP unlike C has more than one way to express false.
PHP waffled on &quot;0&quot;
Originally false
Then true alphanumeric string
Then false b/c of problems with automatic conversions
JS seems to have it both ways
http://stackoverflow.com/questions/7615214/in-javascript-why-is-0-equal-to-false-but-not-false-by-itself
JS sees a non-empty string, ergo it&apos;s true
2nd example: false converts -&gt; 0 and boolean coercision and &quot;0&quot; -&gt; 0 http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/
Arg for: &quot;0&quot; is a string with one character, so true makes sense.
Concerned about type conversion consistency with scalars, unable to make a round trip with &quot;&quot; =&gt; 0 =&gt; &quot;0&quot; when &quot;0&quot; as a boolean expr == true
* The empty() statement was added, which provides an easy to use and a
&gt; reliable way to check if a variable is both set and &apos;non-empty&apos; (if
&gt; (!empty($var))). This provides the &apos;standard&apos; way of checking on
&gt; whether a
&gt; form element coming from GPC has been filled out by the user or not.
from:http://marc.info/?l=php-internals&m=90222483131960&w=2
same day change
b/c only one response and was neutral; willing to use empty():
Arg for: &quot;0&quot; is a string with one character, so true makes sense.
Concerned about type conversion consistency with scalars, unable to make a round trip with &quot;&quot; =&gt; 0 =&gt; &quot;0&quot; when &quot;0&quot; as a boolean expr == true
* The empty() statement was added, which provides an easy to use and a
&gt; reliable way to check if a variable is both set and &apos;non-empty&apos; (if
&gt; (!empty($var))). This provides the &apos;standard&apos; way of checking on
&gt; whether a
&gt; form element coming from GPC has been filled out by the user or not.
from:http://marc.info/?l=php-internals&m=90222483131960&w=2
same day change
b/c only one response and was neutral; willing to use empty():
Arg for: &quot;0&quot; is a string with one character, so true makes sense.
Concerned about type conversion consistency with scalars, unable to make a round trip with &quot;&quot; =&gt; 0 =&gt; &quot;0&quot; when &quot;0&quot; as a boolean expr == true
* The empty() statement was added, which provides an easy to use and a
&gt; reliable way to check if a variable is both set and &apos;non-empty&apos; (if
&gt; (!empty($var))). This provides the &apos;standard&apos; way of checking on
&gt; whether a
&gt; form element coming from GPC has been filled out by the user or not.
from:http://marc.info/?l=php-internals&m=90222483131960&w=2
same day change
b/c only one response and was neutral; willing to use empty():
Arg for: &quot;0&quot; is a string with one character, so true makes sense.
Concerned about type conversion consistency with scalars, unable to make a round trip with &quot;&quot; =&gt; 0 =&gt; &quot;0&quot; when &quot;0&quot; as a boolean expr == true
* The empty() statement was added, which provides an easy to use and a
&gt; reliable way to check if a variable is both set and &apos;non-empty&apos; (if
&gt; (!empty($var))). This provides the &apos;standard&apos; way of checking on
&gt; whether a
&gt; form element coming from GPC has been filled out by the user or not.
from:http://marc.info/?l=php-internals&m=90222483131960&w=2
same day change
b/c only one response and was neutral; willing to use empty():
Re empty:
See http://phpsadness.com/sad/28;
php5.5 can be used with expressions.
Equivalent of a boolean NOT
Today, i.e. PHP5.5+
Anyone can make this mistake; a core dev recently did and when I brought it to his attn, he corrected it publicly.
Maybe s.thing to fix in PHP?
&quot;0.0&quot; follows Perl: &quot;0.0&quot; # not &quot;0&quot; or &quot;&quot; so TRUE
PHP manual 3-&gt;4: controversial change empty(&quot;0&quot;) true!
&quot;0.0&quot; s/b false too!?
Assumption: $items contains something that is countable.
Strategy: check to see if it&apos;s empty / === false || === 0 || === NULL (faster)
$items // perhaps result of $_POST
Count() default return value 1 with scalars unless var is null
1 as in long integer value 1, or as in 1 value; not return true. Per manual returns the count and by default 1 for scalars.
Some have suggested (see http://justinsomnia.org/2007/12/in-php-countfalse-returns-1/) that behind scences the variable gets cast as an array and then counted; untrue!
// zval *array;
Assumption: $items contains something that is countable.
Strategy: check to see if it&apos;s empty / === false || === 0 || === NULL (faster)
$items // perhaps result of $_POST
Count() default return value 1 with scalars unless var is null
1 as in long integer value 1, or as in 1 value; not return true. Per manual returns the count and by default 1 for scalars.
Some have suggested (see http://justinsomnia.org/2007/12/in-php-countfalse-returns-1/) that behind scences the variable gets cast as an array and then counted; untrue!
// zval *array;
Assumption: $items contains something that is countable.
Strategy: check to see if it&apos;s empty / === false || === 0 || === NULL (faster)
$items // perhaps result of $_POST
Count() default return value 1 with scalars unless var is null
1 as in long integer value 1, or as in 1 value; not return true. Per manual returns the count and by default 1 for scalars.
Some have suggested (see http://justinsomnia.org/2007/12/in-php-countfalse-returns-1/) that behind scences the variable gets cast as an array and then counted; untrue!
// zval *array;
Assumption: $items contains something that is countable.
Strategy: check to see if it&apos;s empty / === false || === 0 || === NULL (faster)
$items // perhaps result of $_POST
Count() default return value 1 with scalars unless var is null
1 as in long integer value 1, or as in 1 value; not return true. Per manual returns the count and by default 1 for scalars.
Some have suggested (see http://justinsomnia.org/2007/12/in-php-countfalse-returns-1/) that behind scences the variable gets cast as an array and then counted; untrue!
// zval *array;
Null like a room w/o furniture b/c the furniture is non-existent!
SQL&apos;s NULL : refers to a state rather than a value vs SQL_NULL == 0
PHPNG: zval type_info = IS_NULL (1)
PHP4: 5/2000
PHP project&apos;s greatest strength is its willingness to change. That kind of flexibility has contributed to its longevity.
zend_register_constant(): lowercased name stored in HashTable
Booleans arrive: may 2000 per http://en.wikipedia.org/wiki/PHP
Like True and False is a Zend_constant but its ZVAL value has a data member value (union) that is unset.
Its type IS_NULL and is the only data with this type.
Null means does not exist, i.e. an unset value but some people had a challenging time comprehending, so Zeev spells it out …
This undocumented casting feature for NULL seems ludicrous in light of the foregoing. How do you cast an entity that is unset, bereft of any value to a value of another type?? Undocumented intetionally but why?
Behind the scense:
Assignment of 0 and changing type of NULL.
Code does same thing today except cleaner looking; uses macro.
Added case of IS_UNSET avoided getting undefined variable message
This undocumented casting feature for NULL seems ludicrous in light of the foregoing. How do you cast an entity that is unset, bereft of any value to a value of another type?? Undocumented intetionally but why?
Behind the scense:
Assignment of 0 and changing type of NULL.
Code does same thing today except cleaner looking; uses macro.
Added case of IS_UNSET avoided getting undefined variable message
This undocumented casting feature for NULL seems ludicrous in light of the foregoing. How do you cast an entity that is unset, bereft of any value to a value of another type?? Undocumented intetionally but why?
Behind the scense:
Assignment of 0 and changing type of NULL.
Code does same thing today except cleaner looking; uses macro.
Added case of IS_UNSET avoided getting undefined variable message
Argument for RFC: is_defined() for PHP
JavaScript has such a func – why not PHP?
Copycat arg idiotic – PHP has been a copycat since its inception!
isset alone unable to distinguish between what&apos;s been actually set and unset
validation callbacks
Argument for RFC: is_defined() for PHP
JavaScript has such a func – why not PHP?
Copycat arg idiotic – PHP has been a copycat since its inception!
isset alone unable to distinguish between what&apos;s been actually set and unset
validation callbacks
Argument for RFC: is_defined() for PHP
JavaScript has such a func – why not PHP?
Copycat arg idiotic – PHP has been a copycat since its inception!
isset alone unable to distinguish between what&apos;s been actually set and unset
validation callbacks
Argument for RFC: is_defined() for PHP
JavaScript has such a func – why not PHP?
Copycat arg idiotic – PHP has been a copycat since its inception!
isset alone unable to distinguish between what&apos;s been actually set and unset
validation callbacks
Argument for RFC: is_defined() for PHP
JavaScript has such a func – why not PHP?
Copycat arg idiotic – PHP has been a copycat since its inception!
isset alone unable to distinguish between what&apos;s been actually set and unset
$items // perhaps result of $_POST
Count() default return value 1 with scalars unless var is null
https://bugs.php.net/bug.php?id=46322
Eisberg&apos;s solution works but may be slow (see http://brian.moonspot.net/null-isset-php) per Sjon.
$items // perhaps result of $_POST
Count() default return value 1 with scalars unless var is null
https://bugs.php.net/bug.php?id=46322
Eisberg&apos;s solution works but may be slow (see http://brian.moonspot.net/null-isset-php) per Sjon.
$items // perhaps result of $_POST
Count() default return value 1 with scalars unless var is null
https://bugs.php.net/bug.php?id=46322
Eisberg&apos;s solution works but may be slow (see http://brian.moonspot.net/null-isset-php) per Sjon.
Tjerk Meesters: RFC 12/2013 &quot;Under discussion&quot;
2 options:
A) true-&gt;false, false-&gt;true; no more ++null and not --null
B) true, false and null: ++/-- long ints, ie false=&gt;true and ++true==2;--true=&gt;false and –false=-1;null ++/--
Both cases: seek to replace ++/-- for strings with functions for next major version just as Perl does.
Johannes Schlueter – trouble incrementing var with false val
Felt it makes it harder than necessary for users.
Incrementing and decrementing 0 effect on booleans and can&apos;t decrement NULL.
Patch went no where
-- NULL and ++/-- boolean: no change and no error message
In contrast to JS (EcmaScript)
Derick Rethans reports that Andi G and he had discussed this sit in 2004 and Andi felt best not to tamper with PHP&apos;s design. Why???
Contacted (Andi and) Tjerk … and Jack filled me in with why complicated.
Tjerk Meesters: RFC 12/2013 &quot;Under discussion&quot;
2 options:
A) true-&gt;false, false-&gt;true; no more ++null and not --null
B) true, false and null: ++/-- long ints, ie false=&gt;true and ++true==2;--true=&gt;false and –false=-1;null ++/--
Both cases: seek to replace ++/-- for strings with functions for next major version just as Perl does.
Johannes Schlueter – trouble incrementing var with false val
Felt it makes it harder than necessary for users.
Incrementing and decrementing 0 effect on booleans and can&apos;t decrement NULL.
Patch went no where
-- NULL and ++/-- boolean: no change and no error message
In contrast to JS (EcmaScript)
Derick Rethans reports that Andi G and he had discussed this sit in 2004 and Andi felt best not to tamper with PHP&apos;s design. Why???
Contacted (Andi and) Tjerk … and Jack filled me in with why complicated.
Tjerk Meesters: RFC 12/2013 &quot;Under discussion&quot;
2 options:
A) true-&gt;false, false-&gt;true; no more ++null and not --null
B) true, false and null: ++/-- long ints, ie false=&gt;true and ++true==2;--true=&gt;false and –false=-1;null ++/--
Both cases: seek to replace ++/-- for strings with functions for next major version just as Perl does.
Johannes Schlueter – trouble incrementing var with false val
Felt it makes it harder than necessary for users.
Incrementing and decrementing 0 effect on booleans and can&apos;t decrement NULL.
Patch went no where
-- NULL and ++/-- boolean: no change and no error message
In contrast to JS (EcmaScript)
Derick Rethans reports that Andi G and he had discussed this sit in 2004 and Andi felt best not to tamper with PHP&apos;s design. Why???
Contacted (Andi and) Tjerk … and Jack filled me in with why complicated.
Tjerk Meesters: RFC 12/2013 &quot;Under discussion&quot;
2 options:
A) true-&gt;false, false-&gt;true; no more ++null and not --null
B) true, false and null: ++/-- long ints, ie false=&gt;true and ++true==2;--true=&gt;false and –false=-1;null ++/--
Both cases: seek to replace ++/-- for strings with functions for next major version just as Perl does.
Johannes Schlueter – trouble incrementing var with false val
Felt it makes it harder than necessary for users.
Incrementing and decrementing 0 effect on booleans and can&apos;t decrement NULL.
Patch went no where
-- NULL and ++/-- boolean: no change and no error message
In contrast to JS (EcmaScript)
Derick Rethans reports that Andi G and he had discussed this sit in 2004 and Andi felt best not to tamper with PHP&apos;s design. Why???
Contacted (Andi and) Tjerk … and Jack filled me in with why complicated.
So, how can NULL compare w/Any non-string value or a string?
NULL-&gt;&quot;&quot; and lexical comparison.
In SQL, a field set to NULL can only be compared with IS NULL or IS NOT NULL operators b/c if there isn&apos;t a value how can it be compared with one?
PHP says &quot;Yes, you can by applying boolean logic …
Formerly Manual&apos;s language &quot;Convert to bool&quot; -- language still in Belgium PHP Manual
According to manual null compared with a non-string convert both operands to boolean values
So, how can NULL compare w/Any non-string value or a string?
NULL-&gt;&quot;&quot; and lexical comparison.
In SQL, a field set to NULL can only be compared with IS NULL or IS NOT NULL operators b/c if there isn&apos;t a value how can it be compared with one?
PHP says &quot;Yes, you can by applying boolean logic …
Formerly Manual&apos;s language &quot;Convert to bool&quot; -- language still in Belgium PHP Manual
According to manual null compared with a non-string convert both operands to boolean values
Only care about one of the generated opcodes, IS_SMALLER and operands null and -1; tilde zero is temp var to be echoed.
VM gets constructed and has functions to handle the generated opcode.
Zend_vm_execute.h
Macro invokes fast_is_smaller_function which due to nature of operands in turn calls compare_function (no &apos;:&apos;, etc. in actual source code – this is my pseudo source code).
Null converts to 0 with type IS_BOOL
-1 converts to 1 with type IS_BOOL
So far code corresponds to manual.
Normalize_bool uses ternary with choices -1 or 0 only like strcmp; 1 can&apos;t be choice still NULL can never be greater than anything
Normalize_bool returns an appropriate integer
Null converts to 0 with type IS_BOOL
-1 converts to 1 with type IS_BOOL
So far code corresponds to manual.
Normalize_bool uses ternary with choices -1 or 0 only like strcmp; 1 can&apos;t be choice still NULL can never be greater than anything
Normalize_bool returns an appropriate integer
After PHP5.2 no longer was each operand converted if the the first is null; only the second one is. (see http://lxr.php.net/xref/PHP_5_2/Zend/zend_operators.c#1434)
The choices reflect the capacity of null, ie can be less than op2 or == op2
Resulting -1 appropriate for is_smaller just the way it is in strcmp
Equality …
== is transitive in this case; rare for PHP
How does null == 0?.
Note: expr statement – can do in C and in PHP, too
Again vm machine
Opcode generated
(user who asked AF the ? Was me!)
Macro calls fast_equal_function which calls compare_function w/null and zero
After PHP5.2 no longer was each operand converted if the first is null; only the second one is.
Result of op2 being a truthy value is false so 0 returned as a long int in result
Result of 0 read and it == 0, so equality! Null == 0 is true
Concluding Thoughts …
Next time someone criticizes PHP, ask them:
How much do they know about PHP&apos;s internal workings?
How well do they know the history of the lang and how well do they understand the langs that impacted PHP&apos;s design?
You really should learn C if you don&apos;t already know it and start taking a look at PHP&apos;s sourcecode.
Ask your local PHP Meetup to start a SIG so you can study the sourcecode with others
Result: better communication and collaboration between Userland and the core contributors
You may also contemplate becoming a volunteer for the project and making the codebase and/or documentation better!