Open
Description
Test script:
<?php
$classes = get_declared_classes();
foreach ( $classes as $clazz ) {
$r = new ReflectionClass( $clazz );
if ( !$r->isInstantiable() ) {
continue;
}
try {
new $clazz();
} catch ( ArgumentCountError|TypeError $e ) {
// Nothing
} catch ( Throwable $e ) {
echo $clazz . ": ";
echo get_class( $e ) . ': ' . $e->getMessage() . "\n";
}
}
Failures
For each of the following classes, ReflectionClass::isInstantiable()
returns true, but trying to create an instance of the class directly fails:
Generator: Error: The "Generator" class is reserved for internal use and cannot be manually instantiated
WeakReference: Error: Direct instantiation of WeakReference is not allowed, use WeakReference::create instead
FiberError: Error: The "FiberError" class is reserved for internal use and cannot be manually instantiated
InflateContext: Error: Cannot directly construct InflateContext, use inflate_init() instead
DeflateContext: Error: Cannot directly construct DeflateContext, use deflate_init() instead
CurlHandle: Error: Cannot directly construct CurlHandle, use curl_init() instead
CurlMultiHandle: Error: Cannot directly construct CurlMultiHandle, use curl_multi_init() instead
CurlShareHandle: Error: Cannot directly construct CurlShareHandle, use curl_share_init() instead
CurlSharePersistentHandle: Error: Cannot directly construct CurlSharePersistentHandle, use curl_share_init_persistent() instead
Dba\Connection: Error: Cannot directly construct Dba\Connection, use dba_open() or dba_popen() instead
FFI: Error: Instantiation of FFI is not allowed
FFI\CData: Error: Instantiation of FFI\CData is not allowed
FFI\CType: Error: Instantiation of FFI\CType is not allowed
FTP\Connection: Error: Cannot directly construct FTP\Connection, use ftp_connect() or ftp_ssl_connect() instead
LDAP\Connection: Error: Cannot directly construct LDAP\Connection, use ldap_connect() instead
LDAP\Result: Error: Cannot directly construct LDAP\Result, use the dedicated functions instead
LDAP\ResultEntry: Error: Cannot directly construct LDAP\ResultEntry, use the dedicated functions instead
Directory: Error: Cannot directly construct Directory, use dir() instead
Odbc\Connection: Error: Cannot directly construct Odbc\Connection, use odbc_connect() or odbc_pconnect() instead
Odbc\Result: Error: Cannot directly construct Odbc\Result, use an appropriate odbc_* function instead
PDORow: PDOException: You may not create a PDORow manually
PgSql\Connection: Error: Cannot directly construct PgSql\Connection, use pg_connect() or pg_pconnect() instead
PgSql\Result: Error: Cannot directly construct PgSql\Result, use a dedicated function instead
PgSql\Lob: Error: Cannot directly construct PgSql\Lob, use pg_lo_open() instead
Shmop: Error: Cannot directly construct Shmop, use shmop_open() instead
Soap\Url: Error: Cannot directly construct Soap\Url
Soap\Sdl: Error: Cannot directly construct Soap\Sdl
SysvMessageQueue: Error: Cannot directly construct SysvMessageQueue, use msg_get_queue() instead
SysvSemaphore: Error: Cannot directly construct SysvSemaphore, use sem_get() instead
SysvSharedMemory: Error: Cannot directly construct SysvSharedMemory, use shm_attach() instead
XMLParser: Error: Cannot directly construct XMLParser, use xml_parser_create() or xml_parser_create_ns() instead
Not all of these extensions are on 3v4l but those that are can be confirmed at https://3v4l.org/BmAkH
I didn't test all extensions, what I have enabled locally is:
root@c1c025bca24f:/usr/src/php# php -i | grep "Configure Command"
Configure Command => './configure' '--enable-fpm' '--with-pdo-mysql=mysqlnd' '--with-mysqli=mysqlnd' '--with-pgsql' '--with-pdo-pgsql' '--with-pdo-sqlite' '--enable-intl' '--without-pear' '--with-jpeg' '--with-webp' '--with-avif' '--with-freetype' '--with-xpm' '--enable-exif' '--with-zip' '--with-zlib' '--enable-soap' '--enable-xmlreader' '--with-xsl' '--with-tidy' '--enable-sysvsem' '--enable-sysvshm' '--enable-shmop' '--enable-pcntl' '--enable-mbstring' '--with-curl' '--with-gettext' '--with-bz2' '--with-gmp' '--enable-bcmath' '--enable-calendar' '--enable-ftp' '--with-enchant=/usr' '--enable-sysvmsg' '--with-ffi' '--enable-zend-test' '--enable-dl-test=shared' '--with-ldap' '--with-ldap-sasl' '--with-password-argon2' '--with-mhash' '--with-sodium' '--enable-dba' '--with-cdb' '--enable-flatfile' '--enable-inifile' '--with-tcadb' '--with-lmdb' '--with-qdbm' '--with-snmp' '--with-unixODBC' '--with-pdo-odbc=unixODBC,/usr' '--with-config-file-path=/etc' '--with-config-file-scan-dir=/etc/php.d' '--with-pdo-firebird' '--with-pdo-dblib' '--enable-debug' '--disable-zts'
Proposal
I propose that we add a new class flag, ZEND_ACC_NON_INSTANTIABLE
, that classes can apply when they are registered.