Skip to content

Commit dd9f477

Browse files
nicolas-grekascmb69
authored andcommitted
Declare Transliterator::$id as readonly to unlock subclassing it
Closes GH-9167.
1 parent 962baf7 commit dd9f477

File tree

5 files changed

+36
-67
lines changed

5 files changed

+36
-67
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ PHP NEWS
2323
. Fixed bug GH-9090 (Support assigning function pointers in FFI). (Adam
2424
Saponara)
2525

26+
- Intl:
27+
. Declared Transliterator::$id as readonly to unlock subclassing it. (Nicolas
28+
Grekas)
29+
2630
- PCNTL:
2731
. Fixed pcntl_(get|set)priority error handling for MacOS. (Juan Morales)
2832

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Subclass Transliterator
3+
--EXTENSIONS--
4+
intl
5+
--FILE--
6+
<?php
7+
class ChildTransliterator extends Transliterator
8+
{
9+
public readonly string $id;
10+
11+
public static function new()
12+
{
13+
$tr = (new \ReflectionClass(ChildTransliterator::class))->newInstanceWithoutConstructor();
14+
$tr->id = 'abc';
15+
16+
return $tr;
17+
}
18+
}
19+
20+
21+
$tr = ChildTransliterator::new();
22+
23+
var_dump($tr->id);
24+
?>
25+
--EXPECT--
26+
string(3) "abc"

ext/intl/transliterator/transliterator.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/** @not-serializable */
66
class Transliterator
77
{
8-
public string $id;
8+
public readonly string $id;
99

1010
final private function __construct() {}
1111

ext/intl/transliterator/transliterator_arginfo.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/intl/transliterator/transliterator_class.c

Lines changed: 3 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -144,22 +144,11 @@ static zend_object *Transliterator_clone_obj( zend_object *object )
144144

145145
if( to_orig->utrans != NULL )
146146
{
147-
zval tempz; /* dummy zval to pass to transliterator_object_construct */
148-
149147
/* guaranteed to return NULL if it fails */
150148
UTransliterator *utrans = utrans_clone( to_orig->utrans, TRANSLITERATOR_ERROR_CODE_P( to_orig ) );
151149

152-
if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to_orig ) ) )
153-
goto err;
154-
155-
ZVAL_OBJ(&tempz, ret_val);
156-
transliterator_object_construct( &tempz, utrans,
157-
TRANSLITERATOR_ERROR_CODE_P( to_orig ) );
158-
159-
if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to_orig ) ) )
160-
{
150+
if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to_orig ) ) ) {
161151
zend_string *err_msg;
162-
err:
163152

164153
if( utrans != NULL )
165154
transliterator_object_destroy( to_new );
@@ -173,7 +162,8 @@ static zend_object *Transliterator_clone_obj( zend_object *object )
173162
err_msg = intl_error_get_message( TRANSLITERATOR_ERROR_P( to_orig ) );
174163
zend_throw_error( NULL, "%s", ZSTR_VAL(err_msg) );
175164
zend_string_free( err_msg ); /* if it's changed into a warning */
176-
/* do not destroy tempz; we need to return something */
165+
} else {
166+
to_new->utrans = utrans;
177167
}
178168
}
179169
else
@@ -186,54 +176,6 @@ static zend_object *Transliterator_clone_obj( zend_object *object )
186176
}
187177
/* }}} */
188178

189-
/* {{{ get_property_ptr_ptr handler */
190-
static zval *Transliterator_get_property_ptr_ptr( zend_object *object, zend_string *name, int type, void **cache_slot )
191-
{
192-
if (zend_string_equals_literal(name, "id")) {
193-
return NULL; /* fallback to read_property */
194-
}
195-
return zend_std_get_property_ptr_ptr( object, name, type, cache_slot );
196-
}
197-
/* }}} */
198-
199-
/* {{{ read_property handler */
200-
static zval *Transliterator_read_property( zend_object *object, zend_string *name, int type, void **cache_slot, zval *rv )
201-
{
202-
zval *retval;
203-
204-
if ((type != BP_VAR_R && type != BP_VAR_IS) && zend_string_equals_literal(name, "id")) {
205-
zend_throw_error(NULL, "Transliterator::$id is read-only");
206-
retval = &EG( uninitialized_zval );
207-
} else {
208-
retval = zend_std_read_property( object, name, type, cache_slot, rv );
209-
}
210-
211-
return retval;
212-
}
213-
214-
/* }}} */
215-
216-
/* {{{ write_property handler */
217-
static zval *Transliterator_write_property( zend_object *object, zend_string *name, zval *value,
218-
void **cache_slot )
219-
{
220-
zend_class_entry *scope;
221-
222-
if (EG(fake_scope)) {
223-
scope = EG(fake_scope);
224-
} else {
225-
scope = zend_get_executed_scope();
226-
}
227-
if ((scope != Transliterator_ce_ptr) && zend_string_equals_literal(name, "id")) {
228-
zend_throw_error(NULL, "Transliterator::$id is read-only");
229-
} else {
230-
value = zend_std_write_property( object, name, value, cache_slot );
231-
}
232-
233-
return value;
234-
}
235-
/* }}} */
236-
237179
/* {{{ transliterator_register_Transliterator_class
238180
* Initialize 'Transliterator' class
239181
*/
@@ -246,9 +188,6 @@ void transliterator_register_Transliterator_class( void )
246188
Transliterator_handlers.offset = XtOffsetOf(Transliterator_object, zo);
247189
Transliterator_handlers.free_obj = Transliterator_objects_free;
248190
Transliterator_handlers.clone_obj = Transliterator_clone_obj;
249-
Transliterator_handlers.get_property_ptr_ptr = Transliterator_get_property_ptr_ptr;
250-
Transliterator_handlers.read_property = Transliterator_read_property;
251-
Transliterator_handlers.write_property = Transliterator_write_property;
252191

253192
/* constants are declared in transliterator_register_constants, called from MINIT */
254193

0 commit comments

Comments
 (0)