psalm
psalm copied to clipboard
Add support for new types (like CurlHandle) in PHP8
https://github.com/php/php-src/blob/master/UPGRADING
-
curl_init()
will now return aCurlHandle
object rather than a resource. -
curl_multi_init()
will now return aCurlMultiHandle
object rather than a resource. -
curl_share_init()
will now return aCurlShareHandle
object rather than a resource. -
shmop_open()
will now return aShmop
object rather than a resource. -
enchant_broker_init()
will now return anEnchantBroker
object rather than a resource. - The GD extension now uses objects as the underlying data structure for images, rather than resources.
-
msg_get_queue()
will now return anSysvMessageQueue
object rather than a resource. -
sem_get()
will now return anSysvSemaphore
object rather than a resource. -
shm_attach()
will now return anSysvSharedMemory
object rather than a resource. -
xml_parser_create(_ns
) will now return anXmlParser
object rather than a resource. -
inflate_init()
will now return anInflateContext
object rather than a resource. -
deflate_init()
will now return aDeflateContext
object rather than a resource. -
openssl_x509_read()
andopenssl_csr_sign()
will now return anOpenSSLCertificate
object rather than a resource. -
openssl_csr_new()
will now return anOpenSSLCertificateSigningRequest
object rather than a resource. -
openssl_pkey_new()
will now return anOpenSSLAsymmetricKey
object rather than a resource. - socket_create(), socket_create_listen(), socket_accept(), socket_import_stream(), socket_addrinfo_connect(), socket_addrinfo_bind(), and socket_wsaprotocol_info_import() will now return a
Socket
object rather than a resource. -
socket_addrinfo_lookup()
will now return an array ofAddressInfo
objects rather than resources.
All the related functions that previous took resource
now take the object. is_resource
does not work on them.
If I understand correctly, a CallMap delta for 8.0 needs to be created?
Hey @xPaw, can you reproduce the issue on https://psalm.dev ?
If I understand correctly, a CallMap delta for 8.0 needs to be created?
Yes.
Would also be great to introduce a warning for functions like curl_close
and imagedestroy
to replace them with unset
calls.
One potential solution I thought of for analyzing forward compatibility would be to add a type such as resource<'CurlHandle'>
or resource{CurlHandle}
in the function signature maps and deltas for the older signatures. (e.g. curl_init would return that type, and curl_exec would accept that type as a param type, and so on. A generic resource would be allowed to cast to that type.)
- When analyzing a function such as curl_exec, the presence of
resource{CurlHandle}
would indicate that type is converted to an object in the future, and the error message can mention CurlHandle when warning about is_resource or is_object being potentially wrong in older php versions. (general advice would be to check truthiness instead and delete all references instead of calling*_close()
, or to move checks to a reusable helper method) - This also allows warning about passing a handle for curl_init to curl_multi_init (CurlHandle != CurlMultiHandle) even when targeting older php versions.
- Treating template params differently from regular classes in templates or as a non-template would potentially help avoid false positive warnings about undeclared classes, but the phpdoc parser could probably do that conversion internally.
can you reproduce the issue on https://psalm.dev ?
https://psalm.dev/r/d9103abb4b
I found these snippets:
https://psalm.dev/r/d9103abb4b
<?php
class Secret
{
private \OpenSSLAsymmetricKey $key;
public function __construct(string $pk, string $passphrase)
{
if (!$key = openssl_pkey_get_private($pk, $passphrase)) {
throw new InvalidArgumentException('Unable to load DKIM private key: '.openssl_error_string());
}
$this->key = $key;
}
public function getKey(): \OpenSSLAsymmetricKey
{
return $this->key;
}
}
Psalm output (using commit f496cca):
ERROR: UndefinedClass - 5:13 - Class, interface or enum named OpenSSLAsymmetricKey does not exist
ERROR: InvalidPropertyAssignmentValue - 13:22 - $this->key with declared type 'OpenSSLAsymmetricKey' cannot be assigned type 'resource'
ERROR: UndefinedClass - 16:31 - Class, interface or enum named OpenSSLAsymmetricKey does not exist
@orklah afaik this is implemented already now? (ticket can be closed?)
Looks like we still need:
4.
shmop_open()
will now return aShmop
object rather than a resource. 5.enchant_broker_init()
will now return anEnchantBroker
object rather than a resource. 7.msg_get_queue()
will now return anSysvMessageQueue
object rather than a resource. 8.sem_get()
will now return anSysvSemaphore
object rather than a resource. 9.shm_attach()
will now return anSysvSharedMemory
object rather than a resource. 11.inflate_init()
will now return anInflateContext
object rather than a resource. 12.deflate_init()
will now return aDeflateContext
object rather than a resource.
In the current version (Psalm 4.26.0) I still get false-positives for PHP 8.0:
Class, interface or enum named CurlHandle does not exist (see https://psalm.dev/019)
It is the same message for all CURL related classes and constants (e.g. CURLOPT_URL).
@derrabus OpenSSL snippet now does not produce errors: https://psalm.dev/r/d9103abb4b
I found these snippets:
https://psalm.dev/r/d9103abb4b
<?php
class Secret
{
private \OpenSSLAsymmetricKey $key;
public function __construct(string $pk, string $passphrase)
{
if (!$key = openssl_pkey_get_private($pk, $passphrase)) {
throw new InvalidArgumentException('Unable to load DKIM private key: '.openssl_error_string());
}
$this->key = $key;
}
public function getKey(): \OpenSSLAsymmetricKey
{
return $this->key;
}
}
Psalm output (using commit 8f39de9):
No issues!