You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Added the ::class magic constant: self::class, parent::class and ClassName::class resolve to the fully-qualified class name at compile time, and static::class resolves to the called class at runtime (late static binding) #2527
Trait properties can now have array default values (e.g. trait T { public opts = [1, 2, 3]; }, including empty, keyed and nested arrays). The default is materialized as a persistent immutable array on the trait's class entry, so it is carried into both Zephir classes and PHP userland classes that use the trait, matching native PHP trait semantics. Static array defaults on traits remain rejected (Zephir resolves self:: in a trait to the trait itself, so each using class could not get its own copy) #2607
Class and trait properties can now declare a type, mirroring PHP's typed properties: builtin (int, bool, double, string, array, object), nullable (?string), and class types (<My\Class>, ?<My\Class>). The type is emitted via zend_declare_typed_property, so Reflection reports it and the engine enforces it; a typed property with no default is uninitialized (public <Foo> conn;) rather than null, matching PHP #2608
Added union types (int | float) on method/function parameters and class/trait properties (e.g. public int|float foo;, function f(float|int bar) -> int|float). Reflection reports a ReflectionUnionType; union properties are engine-enforced on write (scalar, null/false, and one or more <Class> members), while a union parameter binds as a mixed value carrying its declared arg-info type mask. Union return types were already supported #2613
Added readonly properties (e.g. public readonly array foo): the property carries ZEND_ACC_READONLY, so Reflection reports it and the engine enforces write-once after initialization. Like PHP, a readonly property must be typed, cannot declare a default value and cannot be static (each rejected at compile time). Enforced on PHP 8.1+; on PHP 8.0 it degrades to a plain typed property #2614
Added the += (add-assign) operator on arrays, performing PHP array union (let a += [1, 2]), for array literals and both array-typed and untyped var operands #1280
Added an opt-in missing-optimizer warning that reports function calls with no applicable optimizer, which are dispatched by name through the Zend function table at runtime instead of being inlined. It also covers calls an existing optimizer declined because it does not handle that call form (e.g. count(a, 0)), which are otherwise invisible. Enable with -wmissing-optimizer; each function is reported once per run, at its first call site #2468
Added a --with-php-config=PATH option to the build, compile and fullclean commands, so an extension can be built against a PHP installation other than the one in the PATH (e.g. a separate ZTS build). phpize is taken from the same directory as the given php-config, and an unusable or mismatched path is rejected before the build starts. Not available on Windows, where the dev-pack (%PHP_DEVPACK%) selects the target PHP #1834
Fixed
Fixed char/uchar values in dynamic (zval) contexts. A string offset read (s[i]) now boxes as a 1-character string when its target is a var/string variable or an array element, matching PHP's $s[$i]: string ch; let ch = s[i]; used to emit C that did not compile, and let pieces[] = s[i]; was rejected with Unknown type: uchar. A declared char/uchar variable still boxes as its integer byte value (as let a = [ch] and return ch already did) — use (string) ch for the character — and a direct return s[i] is unchanged #1629
char/uchar are now accepted in the remaining scalar positions, each of which previously threw or emitted invalid C: (uchar) casts, (string)/(char) casts of a uchar, uchar method parameters and globals, keyed array literals ([1: ch]), let a[k] = ch, object and static property array offsets, and double/bool targets. A char literal reaching a numeric slot no longer emits ZVAL_LONG(&x, ''a''), and assigning an int to a string (string s; let s = i;) no longer emits dead PHP-5 code #1629
Fixed acos() and asin() never using their optimizers on case-sensitive filesystems: optimizer lookup derives AcosOptimizer.php/AsinOptimizer.php from the function name, but the files were named ACosOptimizer.php/ASinOptimizer.php, so both calls compiled to a runtime function call on Linux while macOS and Windows inlined them #2468
Fixed typed-property and array-class-constant string defaults containing escape sequences (e.g. protected string x = "A\\B\\C") being emitted with the wrong byte length: the length was strlen() of the source-escaped PHP value (a \\ counted as two bytes) while the C string literal is shorter, so the runtime string was over-long and corrupted with trailing garbage bytes. The length is now measured by the C compiler (SL() / sizeof), correct for every escape sequence #2617
Fixed the Zephir version has changed warning firing on every rebuild: the version-cache directory existence check used is_file() on a path that is always a directory, so the check never matched and the warning degraded to "warn whenever the project was already built". It now fires only on a genuine version change and names the old and new versions #2621
This discussion was created from the release 1.2.0.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Added
::classmagic constant:self::class,parent::classandClassName::classresolve to the fully-qualified class name at compile time, andstatic::classresolves to the called class at runtime (late static binding) #2527trait T { public opts = [1, 2, 3]; }, including empty, keyed and nested arrays). The default is materialized as a persistent immutable array on the trait's class entry, so it is carried into both Zephir classes and PHP userland classes thatusethe trait, matching native PHP trait semantics. Static array defaults on traits remain rejected (Zephir resolvesself::in a trait to the trait itself, so each using class could not get its own copy) #2607int,bool,double,string,array,object), nullable (?string), and class types (<My\Class>,?<My\Class>). The type is emitted viazend_declare_typed_property, so Reflection reports it and the engine enforces it; a typed property with no default is uninitialized (public <Foo> conn;) rather thannull, matching PHP #2608int | float) on method/function parameters and class/trait properties (e.g.public int|float foo;,function f(float|int bar) -> int|float). Reflection reports aReflectionUnionType; union properties are engine-enforced on write (scalar,null/false, and one or more<Class>members), while a union parameter binds as a mixed value carrying its declared arg-info type mask. Union return types were already supported #2613readonlyproperties (e.g.public readonly array foo): the property carriesZEND_ACC_READONLY, so Reflection reports it and the engine enforces write-once after initialization. Like PHP, a readonly property must be typed, cannot declare a default value and cannot be static (each rejected at compile time). Enforced on PHP 8.1+; on PHP 8.0 it degrades to a plain typed property #2614+=(add-assign) operator on arrays, performing PHP array union (let a += [1, 2]), for array literals and botharray-typed and untypedvaroperands #1280missing-optimizerwarning that reports function calls with no applicable optimizer, which are dispatched by name through the Zend function table at runtime instead of being inlined. It also covers calls an existing optimizer declined because it does not handle that call form (e.g.count(a, 0)), which are otherwise invisible. Enable with-wmissing-optimizer; each function is reported once per run, at its first call site #2468--with-php-config=PATHoption to thebuild,compileandfullcleancommands, so an extension can be built against a PHP installation other than the one in thePATH(e.g. a separate ZTS build).phpizeis taken from the same directory as the givenphp-config, and an unusable or mismatched path is rejected before the build starts. Not available on Windows, where the dev-pack (%PHP_DEVPACK%) selects the target PHP #1834Fixed
char/ucharvalues in dynamic (zval) contexts. A string offset read (s[i]) now boxes as a 1-character string when its target is avar/stringvariable or an array element, matching PHP's$s[$i]:string ch; let ch = s[i];used to emit C that did not compile, andlet pieces[] = s[i];was rejected withUnknown type: uchar. A declaredchar/ucharvariable still boxes as its integer byte value (aslet a = [ch]andreturn chalready did) — use(string) chfor the character — and a directreturn s[i]is unchanged #1629char/ucharare now accepted in the remaining scalar positions, each of which previously threw or emitted invalid C:(uchar)casts,(string)/(char)casts of auchar,ucharmethod parameters and globals, keyed array literals ([1: ch]),let a[k] = ch, object and static property array offsets, anddouble/booltargets. Acharliteral reaching a numeric slot no longer emitsZVAL_LONG(&x, ''a''), and assigning anintto astring(string s; let s = i;) no longer emits dead PHP-5 code #1629acos()andasin()never using their optimizers on case-sensitive filesystems: optimizer lookup derivesAcosOptimizer.php/AsinOptimizer.phpfrom the function name, but the files were namedACosOptimizer.php/ASinOptimizer.php, so both calls compiled to a runtime function call on Linux while macOS and Windows inlined them #2468protected string x = "A\\B\\C") being emitted with the wrong byte length: the length wasstrlen()of the source-escaped PHP value (a\\counted as two bytes) while the C string literal is shorter, so the runtime string was over-long and corrupted with trailing garbage bytes. The length is now measured by the C compiler (SL()/sizeof), correct for every escape sequence #2617Zephir version has changedwarning firing on every rebuild: the version-cache directory existence check usedis_file()on a path that is always a directory, so the check never matched and the warning degraded to "warn whenever the project was already built". It now fires only on a genuine version change and names the old and new versions #2621This discussion was created from the release 1.2.0.
All reactions