New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Invalid error for session_set_save_handler() #737
Comments
https://github.com/JetBrains/phpstorm-stubs/blob/master/session/session.php#L220-L282 Good catch, Side effect of fixing that could be support for "Method Overloading". For contrast |
The callmap used by psalm is one of the most up to date in my experience https://raw.githubusercontent.com/vimeo/psalm/master/src/Psalm/Internal/CallMap.php |
You may be right, it's done using reflection in contrary to user-created phpstorm-stubs, but also don't need to be commented (phpdoc). Intelephense uses phpstorm-stubs because of comments. |
Maybe to begin with but it's now maintained by hand, I have personally submitted manual updates to that file. |
If I'm not mistaken phpstorm stubs started from php.net docs years ago. User changes are unavoidable in both, but scale is a bit different. |
Yeah, psalm doesn't need to show docblock descriptions like intelephense, it only needs the type info. |
I've generated list of functions w/ multiple variants, using file from @ADmad comment. I found 113 functions with 234 variants. abs ( int $number ) : int {}
abs ( float $number ) : float {}
abs ( numeric $number ) : numeric {}
apc_add ( string $key, mixed $var, [ int $ttl ] ) : bool {}
apc_add ( array $values, [ $unused, int $ttl ] ) : array {}
apc_exists ( string $keys ) : bool {}
apc_exists ( string[] $keys ) : array {}
apc_fetch ( string $key, [ bool &$w_success ] ) : mixed|false {}
apc_fetch ( string[] $key, [ bool &$w_success ] ) : array|false {}
apc_store ( string $key, $var, [ int $ttl ] ) : bool {}
apc_store ( array $values, [ $unused, int $ttl ] ) : array {}
apcu_add ( string $key, $var, [ int $ttl ] ) : bool {}
apcu_add ( array<string,mixed> $values, [ $unused, int $ttl ] ) : array<string,int> {}
apcu_exists ( string $keys ) : bool {}
apcu_exists ( string[] $keys ) : array {}
apcu_fetch ( string $key, [ bool &$w_success ] ) : mixed|false {}
apcu_fetch ( string[] $key, [ bool &$w_success ] ) : array|false {}
apcu_store ( string $key, [ $var, int $ttl ] ) : bool {}
apcu_store ( array $values, [ $unused, int $ttl ] ) : array {}
array_diff_uassoc ( array $arr1, array $arr2, callable(mixed,mixed):int $data_comp_func ) : array {}
array_diff_uassoc ( array $arr1, array $arr2, array $arr3, array|callable(mixed,mixed):int $arg4, [ array|callable(mixed,mixed):int ...$rest ] ) : array {}
array_diff_ukey ( array $arr1, array $arr2, callable(mixed,mixed):int $key_comp_func ) : array {}
array_diff_ukey ( array $arr1, array $arr2, array $arr3, array|callable(mixed,mixed):int $arg4, [ array|callable(mixed,mixed):int ...$rest ] ) : array {}
array_intersect_uassoc ( array $arr1, array $arr2, callable(mixed,mixed):int $key_compare_func ) : array {}
array_intersect_uassoc ( array $arr1, array $arr2, array $arr3, array|callable(mixed,mixed):int $arg4, array|callable(mixed,mixed):int ...$rest ) : array {}
array_intersect_ukey ( array $arr1, array $arr2, callable(mixed,mixed):int $key_compare_func ) : array {}
array_intersect_ukey ( array $arr1, array $arr2, array $arr3, array|callable(mixed,mixed):int $arg4, array|callable(mixed,mixed):int ...$rest ) : array {}
array_rand ( array $input, int $num_req ) : int|string|array<int,int>|array<int,string> {}
array_rand ( array $input ) : int|string {}
array_udiff ( array $arr1, array $arr2, callable(mixed,mixed):int $data_comp_func ) : array {}
array_udiff ( array $arr1, array $arr2, array $arr3, array|callable(mixed,mixed):int $arg4, [ array|callable(mixed,mixed):int ...$rest ] ) : array {}
array_udiff_assoc ( array $arr1, array $arr2, callable(mixed,mixed):int $key_comp_func ) : array {}
array_udiff_assoc ( array $arr1, array $arr2, array $arr3, array|callable(mixed,mixed):int $arg4, [ array|callable(mixed,mixed):int ...$rest ] ) : array {}
array_udiff_uassoc ( array $arr1, array $arr2, callable(mixed,mixed):int $data_comp_func, callable(mixed,mixed):int $key_comp_func ) : array {}
array_udiff_uassoc ( array $arr1, array $arr2, array $arr3, array|callable(mixed,mixed):int $arg4, array|callable(mixed,mixed):int $arg5, [ array|callable(mixed,mixed):int ...$rest ] ) : array {}
array_uintersect ( array $arr1, array $arr2, callable(mixed,mixed):int $data_compare_func ) : array {}
array_uintersect ( array $arr1, array $arr2, array $arr3, array|callable(mixed,mixed):int $arg4, [ array|callable(mixed,mixed):int ...$rest ] ) : array {}
array_uintersect_assoc ( array $arr1, array $arr2, callable(mixed,mixed):int $data_compare_func ) : array {}
array_uintersect_assoc ( array $arr1, array $arr2, array $arr3, array|callable $arg4, [ array|callable(mixed,mixed):int ...$rest ] ) : array {}
array_uintersect_uassoc ( array $arr1, array $arr2, callable(mixed,mixed):int $data_compare_func, callable(mixed,mixed):int $key_compare_func ) : array {}
array_uintersect_uassoc ( array $arr1, array $arr2, array $arr3, array|callable(mixed,mixed):int $arg4, array|callable(mixed,mixed):int $arg5, [ array|callable(mixed,mixed):int ...$rest ] ) : array {}
DatePeriod::__construct ( DateTimeInterface $start, DateInterval $interval, int $recur, [ int $options ] ) : void {}
DatePeriod::__construct ( DateTimeInterface $start, DateInterval $interval, DateTimeInterface $end, [ int $options ] ) : void {}
DatePeriod::__construct ( string $iso, [ int $options ] ) : void {}
dba_fetch ( string $key, int $skip, resource $handle ) : string|false {}
dba_fetch ( string $key, resource $handle ) : string|false {}
fscanf ( resource $stream, string $format ) : array {}
fscanf ( resource $stream, string $format, [ string|int|float &...$w_vars ] ) : int {}
getenv ( string $varname, [ bool $local_only ] ) : string|false {}
getenv ( ) : array<string,string> {}
gettimeofday ( ) : array {}
gettimeofday ( [ true $get_as_float ] ) : float {}
hrtime ( [ false $get_as_number ] ) : array{0:int,1:int}|false {}
hrtime ( [ true $get_as_number ] ) : int|float|false {}
ibase_blob_echo ( $link_identifier, string $blob_id ) : bool {}
ibase_blob_echo ( string $blob_id ) : bool {}
ibase_blob_info ( resource $link_identifier, string $blob_id ) : array {}
ibase_blob_info ( string $blob_id ) : array {}
ibase_blob_open ( resource $link_identifier, string $blob_id ) : resource {}
ibase_blob_open ( string $blob_id ) : resource {}
ibase_set_event_handler ( $link_identifier, callable $callback, [ string $event, ...$args ] ) : resource {}
ibase_set_event_handler ( callable $callback, string $event, ...$args ) : resource {}
ibase_wait_event ( $link_identifier, [ string $event, ...$args ] ) : string {}
ibase_wait_event ( string $event, ...$args ) : string {}
implode ( string $glue, array $pieces ) : string {}
implode ( array $pieces ) : string {}
intlcal_set ( IntlCalendar $cal, int $field, int $value ) : bool {}
intlcal_set ( IntlCalendar $cal, int $year, int $month, [ int $dayOfMonth, int $hour, int $minute, int $second ] ) : bool {}
IntlCalendar::set ( int $field, int $value ) : bool {}
IntlCalendar::set ( int $year, int $month, [ int $dayOfMonth, int $hour, int $minute, int $second ] ) : bool {}
IntlGregorianCalendar::set ( int $field, int $value ) : bool {}
IntlGregorianCalendar::set ( int $year, int $month, [ int $dayOfMonth, int $hour, int $minute, int $second ] ) : bool {}
join ( string $glue, array $pieces ) : string {}
join ( array $pieces ) : string {}
levenshtein ( string $str1, string $str2 ) : int {}
levenshtein ( string $str1, string $str2, int $cost_ins, int $cost_rep, int $cost_del ) : int {}
max ( array $arg1 ) : mixed {}
max ( $arg1, $arg2, [ ...$args ] ) : mixed {}
maxdb_stmt::bind_param ( $stmt, string $types, &...$rw_var ) : bool {}
maxdb_stmt::bind_param ( $stmt, string $types, array &$rw_var ) : bool {}
min ( array $arg1 ) : mixed {}
min ( $arg1, $arg2, [ ...$args ] ) : mixed {}
MongoCollection::aggregate ( array $op, [ array $op, array ...$args ] ) : array {}
MongoCollection::aggregate ( array $pipeline, [ array $options ] ) : array {}
mt_rand ( int $min, int $max ) : int {}
mt_rand ( ) : int {}
newrelic_notice_error ( string $message, [ Exception|Throwable $exception ] ) : void {}
newrelic_notice_error ( string $unused_1, string $message, string $unused_2, int $unused_3, [ $unused_4 ] ) : void {}
number_format ( float|int $number, [ int $num_decimal_places ] ) : string {}
number_format ( float|int $number, int $num_decimal_places, string $dec_separator, string $thousands_separator ) : string {}
PDO::query ( string $sql ) : PDOStatement|false {}
PDO::query ( string $sql, int $fetch_column, int $colno ) : PDOStatement|false {}
PDO::query ( string $sql, int $fetch_class, string $classname, array $ctorargs ) : PDOStatement|false {}
PDO::query ( string $sql, int $fetch_into, object $object ) : PDOStatement|false {}
PDOStatement::setFetchMode ( int $mode ) : bool {}
PDOStatement::setFetchMode ( int $fetch_column, int $colno ) : bool {}
PDOStatement::setFetchMode ( int $fetch_class, string $classname, array $ctorargs ) : bool {}
PDOStatement::setFetchMode ( int $fetch_into, object $object ) : bool {}
pg_escape_bytea ( resource $connection, string $data ) : string {}
pg_escape_bytea ( string $data ) : string {}
pg_escape_identifier ( resource $connection, string $data ) : string {}
pg_escape_identifier ( string $data ) : string {}
pg_escape_literal ( resource $connection, string $data ) : string {}
pg_escape_literal ( string $data ) : string {}
pg_escape_string ( resource $connection, string $data ) : string {}
pg_escape_string ( string $data ) : string {}
pg_execute ( resource $connection, string $stmtname, array $params ) : resource|false {}
pg_execute ( string $stmtname, array $params ) : resource|false {}
pg_fetch_object ( resource $result, [ ?int $row, int $result_type ] ) : object {}
pg_fetch_object ( resource $result, [ ?int $row, string $class_name, array $ctor_params ] ) : object {}
pg_fetch_result ( resource $result, string|int $field_name ) : string {}
pg_fetch_result ( resource $result, ?int $row, string|int $field_name ) : string {}
pg_field_is_null ( resource $result, string|int $field_name_or_number ) : int {}
pg_field_is_null ( resource $result, int $row, string|int $field_name_or_number ) : int {}
pg_field_prtlen ( resource $result, $field_name_or_number ) : int|false {}
pg_field_prtlen ( resource $result, int $row, string|int $field_name_or_number ) : int {}
pg_lo_export ( resource $connection, int $oid, string $filename ) : bool {}
pg_lo_export ( int $oid, string $pathname ) : bool {}
pg_lo_import ( resource $connection, string $pathname, $oid ) : int {}
pg_lo_import ( string $pathname, $oid ) : int {}
pg_parameter_status ( resource $connection, string $param_name ) : string|false {}
pg_parameter_status ( string $param_name ) : string|false {}
pg_prepare ( resource $connection, string $stmtname, string $query ) : resource|false {}
pg_prepare ( string $stmtname, string $query ) : resource|false {}
pg_put_line ( resource $connection, string $data ) : bool {}
pg_put_line ( string $data ) : bool {}
pg_query ( resource $connection, string $query ) : resource|false {}
pg_query ( string $query ) : resource|false {}
pg_query_params ( resource $connection, string $query, array $params ) : resource|false {}
pg_query_params ( string $query, array $params ) : resource|false {}
pg_set_client_encoding ( resource $connection, string $encoding ) : int {}
pg_set_client_encoding ( string $encoding ) : int {}
pg_set_error_verbosity ( resource $connection, int $verbosity ) : int {}
pg_set_error_verbosity ( int $verbosity ) : int {}
pg_tty ( [ resource $connection ] ) : string {}
pg_tty ( ) : string {}
pg_untrace ( [ resource $connection ] ) : bool {}
pg_untrace ( ) : bool {}
preg_match ( string $pattern, string $subject, [ string[] &$w_subpatterns, 0| $flags, int $offset ] ) : int|false {}
preg_match ( string $pattern, string $subject, [ array &$w_subpatterns, int $flags, int $offset ] ) : int|false {}
preg_replace_callback ( string|array $regex, callable(array<int, string>):string $callback, string $subject, [ int $limit, int &$w_count ] ) : string|null {}
preg_replace_callback ( string|array $regex, callable(array<int, string>):string $callback, string[] $subject, [ int $limit, int &$w_count ] ) : string[]|null {}
preg_split ( string $pattern, string $subject, ?int $limit, [ null $flags ] ) : array<int,string>|false {}
preg_split ( string $pattern, string $subject, [ ?int $limit, int $flags ] ) : array<int,string>|array[]|false {}
print_r ( mixed $var ) : string {}
print_r ( mixed $var, [ bool $return ] ) : true {}
rand ( int $min, int $max ) : int {}
rand ( ) : int {}
Redis::del ( string $key, string ...$args ) : int {}
Redis::del ( string[] $key ) : int {}
Redis::delete ( string $key, string ...$args ) : int {}
Redis::delete ( string[] $key ) : int {}
Redis::exists ( string $key ) : int {}
Redis::exists ( string[] $key ) : int {}
Redis::set ( string $key, string $value, [ array $options ] ) : bool {}
Redis::set ( string $key, string $value, [ int $timeout ] ) : bool {}
Redis::slave ( string $host, int $port ) : bool {}
Redis::slave ( string $host, int $port ) : bool {}
Redis::unlink ( string $key, string ...$args ) : int {}
Redis::unlink ( string[] $key ) : int {}
RedisArray::delete ( string $key, string ...$args ) : bool {}
RedisArray::delete ( string[] $key ) : bool {}
ReflectionMethod::__construct ( string|object $class, string $name ) : void {}
ReflectionMethod::__construct ( string $class_method ) : void {}
ReflectionProperty::setValue ( object $object, $value ) : void {}
ReflectionProperty::setValue ( $value ) : void {}
runkit_function_add ( string $funcname, string $arglist, string $code, [ ?string $doccomment ] ) : bool {}
runkit_function_add ( string $funcname, Closure $closure, [ ?string $doccomment ] ) : bool {}
runkit_function_redefine ( string $funcname, string $arglist, string $code, [ ?string $doccomment ] ) : bool {}
runkit_function_redefine ( string $funcname, Closure $closure, [ ?string $doccomment ] ) : bool {}
runkit_method_add ( string $classname, string $methodname, string $args, string $code, [ int $flags, ?string $doccomment ] ) : bool {}
runkit_method_add ( string $classname, string $methodname, Closure $closure, [ int $flags, ?string $doccomment ] ) : bool {}
runkit_method_redefine ( string $classname, string $methodname, string $args, string $code, [ int $flags, ?string $doccomment ] ) : bool {}
runkit_method_redefine ( string $classname, string $methodname, Closure $closure, [ int $flags, ?string $doccomment ] ) : bool {}
session_set_cookie_params ( int $lifetime, [ string $path, ?string $domain, bool $secure, bool $httponly ] ) : bool {}
session_set_cookie_params ( array{lifetime?:int,path?:string,domain?:?string,secure?:bool,httponly?:bool} $options ) : bool {}
session_set_save_handler ( callable(string,string):bool $open, callable():bool $close, callable(string):string $read, callable(string,string):bool $write, callable(string):bool $destroy, callable(string):bool $gc, [ callable():string $create_sid, callable(string):bool $validate_sid, callable(string):bool $update_timestamp ] ) : bool {}
session_set_save_handler ( SessionHandlerInterface $sessionhandler, [ bool $register_shutdown ] ) : bool {}
setcookie ( string $name, [ string $value, int $expires, string $path, string $domain, bool $secure, bool $httponly ] ) : bool {}
setcookie ( string $name, [ string $value, array $options ] ) : bool {}
setlocale ( int $category, string|0|null $locale, [ string ...$args ] ) : string|false {}
setlocale ( int $category, ?array $locale ) : string|false {}
SimpleXMLElement::asXML ( string $filename ) : bool {}
SimpleXMLElement::asXML ( ) : string|false {}
stream_context_set_option ( $context, string $wrappername, string $optionname, $value ) : bool {}
stream_context_set_option ( $context, array $options ) : bool {}
strtok ( string $str, string $token ) : string|false {}
strtok ( string $token ) : string|false {}
strtr ( string $str, string $from, string $to ) : string {}
strtr ( string $str, array $replace_pairs ) : string {}
SWFShape::addFill ( int $red, int $green, int $blue, [ int $alpha, swfbitmap $bitmap, int $flags, swfgradient $gradient ] ) : SWFFill {}
SWFShape::addFill ( SWFBitmap $bitmap, [ int $flags ] ) : SWFFill {}
SWFShape::addFill ( SWFGradient $gradient, [ int $flags ] ) : SWFFill {}
uopz_backup ( string $class, string $function ) : void {}
uopz_backup ( string $function ) : void {}
uopz_copy ( string $class, string $function ) : Closure {}
uopz_copy ( string $function ) : Closure {}
uopz_delete ( string $class, string $function ) : void {}
uopz_delete ( string $function ) : void {}
uopz_flags ( string $class, string $function, int $flags ) : int {}
uopz_flags ( string $function, int $flags ) : int {}
uopz_function ( string $class, string $function, Closure $handler, [ int $modifiers ] ) : void {}
uopz_function ( string $function, Closure $handler, [ int $modifiers ] ) : void {}
uopz_get_hook ( string $class, string $function ) : ?Closure {}
uopz_get_hook ( string $function ) : ?Closure {}
uopz_redefine ( string $class, string $constant, mixed $value ) : bool {}
uopz_redefine ( string $constant, mixed $value ) : bool {}
uopz_rename ( string $class, string $function, string $rename ) : void {}
uopz_rename ( string $function, string $rename ) : void {}
uopz_restore ( string $class, string $function ) : void {}
uopz_restore ( string $function ) : void {}
uopz_set_hook ( string $class, string $function, Closure $hook ) : bool {}
uopz_set_hook ( string $function, Closure $hook ) : bool {}
uopz_set_return ( string $function, mixed $value, [ string $class, bool $execute ] ) : bool {}
uopz_set_return ( string $function, mixed $value, [ bool $execute ] ) : bool {}
uopz_undefine ( string $class, string $constant ) : bool {}
uopz_undefine ( string $constant ) : bool {}
uopz_unset_hook ( string $class, string $function ) : bool {}
uopz_unset_hook ( string $function ) : bool {}
uopz_unset_return ( string $function, [ string $class ] ) : bool {}
uopz_unset_return ( string $function ) : bool {}
version_compare ( string $ver1, string $ver2, '\x3c'|'lt'|'\x3c='|'le'|'\x3e'|'gt'|'\x3e='|'ge'|'=='|'='|'eq'|'!='|'\x3c\x3e'|'ne' $oper ) : bool {}
version_compare ( string $ver1, string $ver2, [ $oper ] ) : int {}
wincache_ucache_add ( string $key, mixed $value, [ int $ttl ] ) : bool {}
wincache_ucache_add ( array $values, [ $unused, int $ttl ] ) : bool {}
wincache_ucache_set ( $key, $value, [ int $ttl ] ) : bool {}
wincache_ucache_set ( array $values, [ $unused, int $ttl ] ) : bool {}
XSLTProcessor::setParameter ( string $namespace, string $name, string $value ) : bool {}
XSLTProcessor::setParameter ( string $namespace, array $options ) : bool {}
Yaf_Controller_Abstract::forward ( string $action, [ array $parameters ] ) : void {}
Yaf_Controller_Abstract::forward ( string $controller, string $action, [ array $parameters ] ) : void {}
Yaf_Controller_Abstract::forward ( string $module, string $controller, string $action, [ array $parameters ] ) : void {}
ZMQSocket::send ( array $message, [ int $mode ] ) : ZMQSocket {}
ZMQSocket::send ( string $message, [ int $mode ] ) : ZMQSocket {}
// Functions: 113 / Variants: 234 |
fixed in 1.3.3 |
@KaduAmaral What error you have? What type are |
Same error of issue #859, Invalid number of arguments. In case my My version is 1.3.3. |
After last updates it's not throwing errors even for this |
I've tried uninstall/reinstall, but is still showing the message. How can I reindex? |
When any php file is open: |
I can confirm that error is no longer generated with usage like |
@KapitanOczywisty I don't see how that relates to my issue. My call to |
tl;dr there were cases when types were incompatible when they wouldn't irl and author made type checking more relaxed. It's not related to function overloading itself. |
@bmewburn Thanks |
Describe the bug
session_set_save_handler() has two prototypes. One requires only 2 arguments. Using that prototype (with correct argument types) intelephense incorrectly reports that
Expected 6 arguments. Found 2
.To Reproduce
session_set_save_handler($handlerObject, false)
Expected behavior
No error to be reported.
The text was updated successfully, but these errors were encountered: