summaryrefslogtreecommitdiff
path: root/CHANGES-3.0
blob: b3b9d8bea56cd7ebf500fab91de842bf08902ef9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
Noticeable Changes between PHP/FI 2.0 and PHP 3.0
=================================================

This file was designed to be viewed with a tab size of 4 characters.

This file is divided into 4 sections:
1.  Downwards incompatible language changes.  This section includes all of
    the changes in the core language which may require people to modify
    their scripts before using them with PHP 3.0.  It does NOT list
    changes made in the behavior of specific functions.
2.  New language features.  This section includes all of the new additions
    to the core language, that may be used to enhance scripts designed for
    PHP 3.0.  Likewise, it does not include a listing of new functions.
3.  Structural changes not directly effecting the end user.  The core
    of PHP 3.0 is a complete rewrite.  As such, many issues effecting
    PHP/FI 2.0 were addressed and vastly improved in this version,
    resulting in a much more stable and efficient implementation.  This
    section lists these changes in design.
4.  Other changes that don't fit in any of the above categories.

Please remember that PHP 3.0's core is a complete rewrite, and thus,
there may be other undocumented incompatibilities we haven't thought
of ourselves.  If you think you've found a incompatibility (or a new
feature) which is not listed here, please mail us at
php-dev@php.iquest.net.



												- Zeev

------------------------------------------------------------------------------

Downwards incompatible language changes
=======================================

[1]	The close-PHP tag has changed from > to ?>

	This means that instead of writing:

	<?echo $title;>

	You should write:

	<?echo $title;?>

	PHP3 also includes support for a longer-form start tag that is
	XML-compliant:

	<?php echo $title;?>

	The ability to use the short start tag ('<?') can be turned on and
	off using the short_tags() function. Whether it is enabled or not by
	default is a compile-time option (normally set to enabled by default).


[2]	Semicolons in if/elseif/else must be replaced with colons.

	For example, the equivalent of:

		if (expr);
		  statements
		  ...
		elseif (expr);
		  statements
		  ...
		else;
		  statements
		endif;

	in PHP 3.0 would be:

		if (expr):
		  statements
		  ...
		elseif (expr):
		  statements
		  ...
		else:
		  statements
		endif;

	Note that the endif is followed by a semicolon and not a colon even in
	PHP 3.0, which marks the end of the entire IF sentence.

	Also note that the implementation of the colon-mode and curly-braces
	mode in PHP 3.0 is identical, one isn't buggier than the other (note
	that I'm not saying they're not buggy, though :)


[3]	Semicolons in while loops must also be replaced with colons.

	For example, the equivalent of:

		while (expr);
		  statements
		  ...
		endwhile;

	in PHP 3.0 would be:

		while (expr):
		  statements
		  ...
		endwhile;

	Note that the endwhile is followed by a semicolon and not a colon even
	in PHP 3.0, which marks the end of the WHILE sentence.  As with the IF
	statement, the implementation of the colon-mode and curly-braces mode
	in PHP 3.0 is identical, one isn't buggier than the other.

	Also note that failing to change the semicolon to a colon can result in
	scripts that get stuck in the while loop because the loop-condition never
	changes.


[4]	$foo[0] is no longer identical to $foo.

	In PHP/FI 2.0, a side-effect of the implementation caused $foo[0] to be
	identical to $foo.  This is not the case in PHP 3.0.


[5]	Expressions determine their types differently.

	The way expressions are evaluated has changed radically in PHP 3.0.
	Expressions are no longer given the type of the left argument, but are
	assigned types taking both types into account, and regardless of which
	is on the left side and which is on the right side.  On simple scripts
	that should probably not effect you, but if you've relied on this fact
	(even without realizing you do) it may change the way your scripts work.
	Consider the next example:

		$a[0]=5;
		$a[1]=7;

		$key = key($a);
		while ("" != $key) {
			echo "$key\n";
			next($a);
		}


	In PHP/FI 2.0, this would display both of $a's indices.  In PHP 3.0, it
	wouldn't display anything.  The reason is that in PHP/FI 2.0, because the
	left argument's type was string, a string comparison was made, and indeed
	"" does not equal "0", and the loop went through.  In PHP 3.0, when a
	string is compared with an integer, an integer comparison is made (the
	string is converted to an integer).  This results in comparing atoi("")
	which is 0, and $key which is also 0, and since 0==0, the loop doesn't
	go through even once.  The fix for this is simple, by replacing the
	while statement with:

		while ("" != stringval($key)) {

	This would first convert the integer 0 to a string "0", and then
	compare "" and "0", which are not equal, and the loop would go through
	as expected.  As mentioned later, casting operators are supported in
	PHP 3.0 for a quicker and more readable way of changing variables'
	types. For example, you could use:

		while ("" != (string)$key) {


[6]	The structure of error messages has changed.

	Although the error messages are usually more accurate, you won't be shown
	the actual line of text and actual place in which the error occured.
	You'll be supplied with the line number in which the error has occured,
	though.


[7]	The format string argument to echo is no longer supported.

	Use printf(format,arg1,arg2,arg3,...) instead (unlimited arguments).


[8]	The use of read-mode $array[] is no longer supported.

	That is, you cannot traverse an array by having a loop that does $data =
	$array[].  Use current() and next() instead.  Also, $array1[] = $array2
	does not append the values of $array2 to $array1, but appends $array2
	as the last entry of $array1 (see the multidimensional array support).


[9]	Apache versions older than 1.2 are not supported anymore.

	The apache module requires apache 1.2 or later (1.3-beta is supported).


[10] Indirect references inside quoted strings

	PHP2-style indirect reference inside quoted strings is no longer
    supported.  That is, if $foo="bar", and $bar="abc", in PHP2,
    "$$foo" would print out "abc".  In PHP3, this would print
    "$bar" (the contents of $foo is replaced with "bar").
    To use indirect reference in PHP3 inside quoted strings, you should use 
    the new notation: "${$foo}".  The standard $$foo notation will work
    outside of the quoted string.

[11]
		Some functions have changed names, are missing, or have been deprecated
		by other functions

	As a whole new rewrite, written by many more people and supporting many
	more APIs than it's predecessor, there's a good chance some of the functions
	you're used to from PHP/FI 2 aren't available in release 3, or have changed
	names.  Many functions that do exist behave a bit differently, mainly
	because they return different values for errors (false) but also for other
	reasons.  We can't list all of these functions here, simply because drawing
	a full comparison between the function sets of the two versions is way too
	much work.  If a converted PHP/FI 2 script doesn't work for you, nothing
	can replace the good old human eye going over the code, doublechecking
	with the online manual that each function still does what you expected it
	to do.

[12]	Other incompatibilities.

	It's not too unlikely that other documented behavior of PHP2 has changed
	in this release.  If you think you've found an example, please mail
	us at php-dev@php.iquest.net.  Even if you've found an undocumented
	feature of PHP2 that stopped working in PHP3, we'd like to know about it
	(although it's more than likely that it will not be supported).



------------------------------------------------------------------------------


New Language Features
=====================

[1]	Expressions

	PHP 3.0 includes a rich implementation of expressions, much more advanced
	than this of 2.0.  Just about any complex C-like or perl-like expression
	would work.  Support was added for assignment operators (+=, -=, *= etc),
	pre and post increment/decerement (e.g. $i++, ++$i) and the questionmark
	operator ( (expr?expr:expr) ).  Every assignment is now an expression
	with a value, which means stuff like $a = $b = $c = $d = 0;  would work.
	It is difficult to describe the power of expressions within a few lines
	of text, but if you're familiar with them, you probably get the picture.


[2]	for loops are now supported.

	for loops were fairly difficult to implement (in fact, we didn't find
	any parallel interpreter that supports for loops anywhere (no, perl is
	not an interpreter)).  The bottom line is that for loops work, and are
	around 5% slower than comparable while loops (that may vary), but often
	they're much nicer.

	The syntax is identical to the one of C:

		for (expr; expr; expr) statement;

	or

		for (expr; expr; expr) { statements ... }

	The first expression is executed the first time the loop is encountered,
	the loop is run as long as the second expression is evaluated as TRUE,
	and after each iteration, the 3rd expression is evaluated.

	Colon-mode FOR loops are also supported:
	for (expr; expr; expr):
		statements
		...
	endfor;


[3]	do..while(expr) loops are now supported.

	Like with its C parallel, the statements inside a do..while loop are
	run once the first time the loop is encountered, and then as long as
	the expression evaluates as true.

	For example:

		do {
			statements;
		} while ($i++ < $max);


[4]	break and continue statements are now supported inside loops.

	You can break out of loops, or continue to the next iteration of the
	loop using these statements.  A special feature of PHP is the ability
	to specify an expression argument to break or continue, which specifies
	how many loops you want to break out from or continue to.  For example:

		for ($i=0; $i<10; $i++) {
			for ($j=0; $j<10; $j++) {
				if ($j>5)
					break;
				if ($i>5)
					break 2;
			}
		}
	
	The first break statement would end the inner loop every time $j is
	greater than 5.  The second break statement would end both the inner
	and outer loop when $i is greater than 5.

	Note:  For this matter, switch statements are considered as loops.  So
	if you write "break 2;" inside a switch statement, you would be asking
	to break out of the switch, and the innermost loop in which is nested.


[5]	Switched to C-style declaration of functions.

	Here's a pretty useless function which makes a good example:

		function concat($str1,$str2)
		{
			return $str1.$str2;
		}

	NOTE:	The old style function definition is still supported, to
			allow easier upgrading from PHP/FI 2.0 scripts.  Simply
			change 'function' to 'old_function' for these functions.


[6]	OOP support

	Classes and inheritance are supported to a limited extent in PHP 3.0.
	Here's how to declare a simple class:

		class simple_class {
			var $property1,$property2;
			var $property3=5;

			function display() {
				printf("p1=%d, p2=%d, p3=%d\n",
					$this->property1,
					$this->property2,
					$this->property3);
			}
			function init($p1,$p2) {
				$this->property1 = $p1;
				$this->property2 = $p2;
			}
		};

	Here's how to create an object of that class:

		$obj = new simple_class;

	At this point, $obj is an object with 2 uninitialized variables, 1
	initialized variable, and 2 member functions.  No protection is made on
	the internals of the object, and using its properties is simple:

		$obj->property1 = 7;

	would assign 7 to $property1 inside $obj.  Calling member functions is
	also simple:

		$obj->display()

	would run the display() member function of $obj.  Note that the
	implementation of display() uses the special variable $this, which is
	replaced with the object the function is called on.

	Inheritance is pretty simple too:

		class complex_class extends simple_class {
			var $property4="test";

			function display() {
				printf("p1=%d, p2=%d, p3=%d, p4=%d\n",
					$this->property1,
					$this->property2,
					$this->property3,
					$this->property4);
			}
		}	

	Basically, the class complex_class inherits everything from its parent,
	simple_class, except properties or member functions which override the
	ones in the parent.  In this example, since we supply an alternative
	display() function, it would be used with complex_class objects instead
	of the display() function that was declared in simple_class.  On the other
	hand, since we don't supply an alternative init() function, complex_class
	objects would have the same init() function as simple_class objects do.

	As with expressions, it's impossible to teach OOP in a few lines, and
	personally I'm unclear as to how useful this would be in day to day
	scripting.  If you like this, play with this until you figure it out :)

	Objects can reside in arrays, and can contain arrays.  However,
	a limitation of the current implementation doesn't allow an object
	to contain an array of objects (actually, this is allowed, but
	there's no way to address the properties of such an object directly,
	but only indirectly).  For example, assuming $a[3] is an object,
	$a[3]->b[2] is an object as well, you can't address the properties
	of $a[3]->b[2] (i.e. you can't write $a[3]->b[2]->foo = "bar", for
	instance).  


[7]	Function pointers are now supported.

	A simple illustrative example:

		$func_ptr = "time";
		$current_time = $func_ptr();

	is identical to

		$current_time = time();


[8]	Indirect references are much more powerful.

	For example, one can use the dollar operator an infinite amount of times:

		$a = "b";
		$b = "c";
		$c = "d";
		$d = "e";
		$e = "Testing\n";

		echo $$$$$a;

	Would display $e's content, which is "Testing\n".

	In addition, one can use complex expressions to generate variable names
	using a perl-like notation:

		$i="123";
		${"test".$i} = 5;

	would assign 5 to $test123.

[9]	A string concatenation operator was added, '+' no longer concatenates strings.

	A perl-like string concatenation operator was added, the '.' operator.
	It converts both of its arguments to strings, and concatenates them.
	For example:

		$result = "abcd".5;

	assigns "abcd5" to result.  Note that under PHP 3.0, the '+' operator
	no longer performs concatenation if its arguments are strings.  Use
	the '.' operator instead.

[10]	Supports passing function arguments by references instead of by value.

	Support for passing function arguments by reference instead of by value
	has been added.  This doesn't result in having to change the function
	implementations in any way, but, when calling the function, you can
	decide on whether the variable you supply would actually be changed by
	the function, or a copy of it.

	Example:

		function inc($arg)
		{
			$arg++;
		}

		$i=0;
		inc($i);  # here $i in the outer scope wouldn't change, and remain 0
		inc(&$i); # here $i is passed by reference, and would change to 1


[11]	Support for multidimensional arrays.

	(Or as Andi calls them, 'hyperdimensional variables'.)

	The easiest way to define this support of PHP 3.0 is inductive -
	arrays can contain any type of variables, including other arrays.
	A simple example:

		$a[0]=5;
		$a[1]["testing"]=17;
		$b["foo"]=$a;

	Ok, so it may be not so simple.  Play with it, it's pretty powerful.


[12]	Array initialization is now supported.

	For example, let's say you want to initialize a lookup table to convert
	number to month names:

		$months = array("January", "February", "March",
						"April", "May", "June", "July", "August",
				 		"September", "October", "November", "December");

	would assign $months[0] to be January, $months[1] to be February, etc.
	Alternately, you may want the count to start at '1' instead of 0.
	You can do so easily:

		$months = array(1=>"January", "February", "March",
						"April", "May", "June", "July", "August",
						"September", "October", "November", "December");

	Also, you can specify an index for every entry, not just the first one:

		$first_names = array("Doe"=>"John", "Gates"=>"William",
							"Clinton"=>"Bill" });

	would assign $first_names["Doe"]="John", etc.


[13]	Perl style lists now supported.

	Multiple values from arrays may now be assigned into several
	variables using one assignment.  For example:
	
		$str = "johndoe:x:555:555:Doe, John:/home/johndoe:/bin/tcsh";
		
		list($username,$passwd,$uid,$gid,$realname,$homedir,$shell) = 
			explode(":",$str);
	
	Would assign 'johndoe' into $username, 'x' into $passwd, etc.


[14]	Colons are supported in 'case' and 'default' statements.

	For example:

		switch($value) {
			case 'A':
				statement;
				break;
			case 'B':
				statement;
				break;
			case 'C':
				statement;
				/* fall-through */
			default:
				statement;
		}
	
	Semicolons are still supported, but when writing new scripts, they
	should be phased out in favour of colons.


------------------------------------------------------------------------------


Non Language Related New Features
=================================

[1]	Persistent resource lists.

	In plain english this means that there's now an easy way of writing the
	SQL drivers so that they don't open and close the SQL link every time,
	but instead open it the first time it's required, and then use it on
	every later hit.  As of PHP 3.0a1, only the MySQL, mSQL and PostgresSQL
	drivers have been changed (rewritten) to take advantage of this option.
	To use it, use mysql_pconnect() instead of mysql_connect() (or the
	equivalents for the two other databases).


[2]	Configuration file.

	PHP now has its own configuration file, and many compile-time options
	of PHP2 are now configurable at runtime.


[3]	Syntax Highlighting.

	A syntax highlighter has been built into PHP 3.0, which means PHP 3.0 can
	display your code, syntax highlighted, instead of executing it.
	There are currently two ways to use the syntax highlighter.  One is to
	use the show_source() statement.  This statement is identical to the
	include() statement, except instead of executing the file, it displays
	its source syntax highlighted.
	The second way is possible only when running as an apache module, and is
	to define a special extension for PHP 3.0 source files (e.g. .php3s)
	and instruct apache to automatically syntax highlight them.


[4]	Loadable modules.

	This would have a huge impact on the Windows version, and would probably
	be used in the UNIX environment as well.  One can now add PHP internal
	functions in runtime by loading a dynamic module.  This is known to work
	under Solaris, Linux and Win32 at this time, but would be ported to any
	other capable platform if an incompatability is found.


------------------------------------------------------------------------------


Other Interesting Issues
========================


[1]	Improved performance.

	The performance of PHP 3.0 is much better than the one of PHP/FI 2.0.
	Memory consumption has been dramatically reduced in many cases, due
	to the use of an internal memory manager, instead of apache's pools.
	Speedwise, PHP 3.0 is somewhere between 2 and 3 times faster than
	PHP/FI 2.0.


[2]	More reliable parser.

	After PHP 3.0 is well tested, it'll be pretty safe to say that it's
	more reliable than PHP/FI 2.0 is.  While PHP/FI 2.0 performed well on
	simple, and fairly complex scripts, a fundamental design difference
	from PHP 3.0 makes it more prone to errors.  In PHP 3.0, obscure parser
	problems are much less likely.


[3]	Improved C API.

	If you're a C coder, adding functionality to PHP was never easier.
	A pretty well documented API is available (apidoc.txt), and you no longer
	have to touch the parser or scanner code when adding your function.
	Also, it's more complicated to 'go wrong' when implementing a PHP3
	function than it was in PHP2 (no stack to maintain) - but of course,
	you can mess up here too :)


[4]	Name change.

	PHP/FI 2.0 was renamed to PHP 3.0, and the meaning has changed from
	'Personal Home Pages / Forms Interpreter' to 'PHP: Hypertext Preprocessor'.
	'Personal' home pages was an understatement for PHP/FI 2.0, and is
	definitely an understatement for PHP 3.0.