For Intelephense to work effectively it must have access to the definitions of the symbols used in your code. It does this by scanning the php files found in the workspace. Sometimes PHP files may have a non standard extension. It is important to associate these extensions with PHP using the intelephense.files.associations configuration option.
intelephense.files.associations
{
"type": "array",
"default": [
"*.php",
"*.phtml"
],
"description": "Configure glob patterns to make files available language server features. Inherits from files.associations.",
"scope": "window"
}You may have large files in your workspace that by default Intelephense will skip. You can configure the maximum file size with the intelephense.files.maxSize option.
intelephense.files.maxSize
{
"type": "number",
"default": 1000000,
"description": "Maximum file size in bytes.",
"scope": "window"
}There may be files you do not want to indexed by Intelephense. It is important in large projects to exclude unnecessary files to avoid polluting suggestion lists and degrading performance.
intelephense.files.exclude
{
"type": "array",
"items": {
"type": "string"
},
"default": [
"**/.git/**",
"**/.svn/**",
"**/.hg/**",
"**/CVS/**",
"**/.DS_Store/**",
"**/node_modules/**",
"**/bower_components/**",
"**/vendor/**/{Tests,tests}/**",
"**/.history/**",
"**/vendor/**/vendor/**"
],
"description": "Configure glob patterns to exclude certain files and folders fro all language server features. Inherits from files.exclude.",
"scope": "resource"
}Sometimes symbol definitions are not in your workspace but are core PHP symbols or defined in an extension. For this reason Intelephense includes stub definitions for many of these. Extensions that are bundled with PHP are enabled by default. You can configure what other symbols are available in your environment with the intelephense.stubs option.
intelephense.stubs
{
"type": "array",
"items": {
"type": "string",
"enum": [
"amqp",
"apache",
"apcu",
"bcmath",
"blackfire",
"bz2",
"calendar",
"cassandra",
"com_dotnet",
"Core",
"couchbase",
"crypto",
"ctype",
"cubrid",
"curl",
"date",
"dba",
"decimal",
"dom",
"ds",
"enchant",
"Ev",
"event",
"exif",
"fann",
"FFI",
"ffmpeg",
"fileinfo",
"filter",
"fpm",
"ftp",
"gd",
"gearman",
"geoip",
"geos",
"gettext",
"gmagick",
"gmp",
"gnupg",
"grpc",
"hash",
"http",
"ibm_db2",
"iconv",
"igbinary",
"imagick",
"imap",
"inotify",
"interbase",
"intl",
"json",
"judy",
"ldap",
"leveldb",
"libevent",
"libsodium",
"libxml",
"lua",
"lzf",
"mailparse",
"mapscript",
"mbstring",
"mcrypt",
"memcache",
"memcached",
"meminfo",
"meta",
"ming",
"mongo",
"mongodb",
"mosquitto-php",
"mqseries",
"msgpack",
"mssql",
"mysql",
"mysql_xdevapi",
"mysqli",
"ncurses",
"newrelic",
"oauth",
"oci8",
"odbc",
"openssl",
"parallel",
"Parle",
"pcntl",
"pcov",
"pcre",
"pdflib",
"PDO",
"pdo_ibm",
"pdo_mysql",
"pdo_pgsql",
"pdo_sqlite",
"pgsql",
"Phar",
"phpdbg",
"posix",
"pspell",
"pthreads",
"radius",
"rar",
"rdkafka",
"readline",
"recode",
"redis",
"Reflection",
"regex",
"rpminfo",
"rrd",
"SaxonC",
"session",
"shmop",
"SimpleXML",
"snmp",
"soap",
"sockets",
"sodium",
"solr",
"SPL",
"SplType",
"SQLite",
"sqlite3",
"sqlsrv",
"ssh2",
"standard",
"stats",
"stomp",
"suhosin",
"superglobals",
"svn",
"sybase",
"sync",
"sysvmsg",
"sysvsem",
"sysvshm",
"tidy",
"tokenizer",
"uopz",
"uv",
"v8js",
"wddx",
"win32service",
"winbinder",
"wincache",
"wordpress",
"xcache",
"xdebug",
"xhprof",
"xml",
"xmlreader",
"xmlrpc",
"xmlwriter",
"xsl",
"xxtea",
"yaf",
"yaml",
"yar",
"zend",
"Zend OPcache",
"ZendCache",
"ZendDebugger",
"ZendUtils",
"zip",
"zlib",
"zmq",
"zookeeper"
]
},
"default": [
"apache",
"bcmath",
"bz2",
"calendar",
"com_dotnet",
"Core",
"ctype",
"curl",
"date",
"dba",
"dom",
"enchant",
"exif",
"FFI",
"fileinfo",
"filter",
"fpm",
"ftp",
"gd",
"gettext",
"gmp",
"hash",
"iconv",
"imap",
"intl",
"json",
"ldap",
"libxml",
"mbstring",
"meta",
"mysqli",
"oci8",
"odbc",
"openssl",
"pcntl",
"pcre",
"PDO",
"pdo_ibm",
"pdo_mysql",
"pdo_pgsql",
"pdo_sqlite",
"pgsql",
"Phar",
"posix",
"pspell",
"readline",
"Reflection",
"session",
"shmop",
"SimpleXML",
"snmp",
"soap",
"sockets",
"sodium",
"SPL",
"sqlite3",
"standard",
"superglobals",
"sysvmsg",
"sysvsem",
"sysvshm",
"tidy",
"tokenizer",
"xml",
"xmlreader",
"xmlrpc",
"xmlwriter",
"xsl",
"Zend OPcache",
"zip",
"zlib"
],
"description": "Configure stub files for built in symbols and common extensions.The default setting includes PHP core and all bundled extensions.",
"scope": "window"
}
Other configuration settings that allow you to further define the PHP environment include:
intelephense.environment.documentRoot
{
"type": "string",
"description": "The directory of the entry point to the application (index.php).Defaults to the first workspace folder. Used for resolving script inclusion.",
"scope": "window"
}intelephense.environment.includePaths
{
"type": "array",
"items": {
"type": "string"
},
"description": "The include paths (as individual path items) as defined in theinclude_path ini setting. Used for resolving script inclusion.",
"scope": "window"
}intelephense.environment.phpVersion
{
"type": "string",
"default": "7.4.0",
"description": "A semver compatible string that represents the target PHP version.Used for providing version appropriate suggestions and diagnostics. PHP 5.3.0 andgreater supported.",
"scope": "window"
}intelephense.environment.shortOpenTag
{
"type": "boolean",
"default": false,
"description": "When enabled '<?' will be parsed as a PHP open tag. Defaults tofalse.",
"scope": "window"
}You will get more out of Intelephense if you provide type declarations and/or type annotations. Where possible types will be inferred but there are places where it is difficult or impossible to determine the type. Class properties and function and method parameters are examples where this is very important. Providing type declarations and/or annotations may also improve performance as Intelephense does not need to dig through too much code to determine types. When a type cannot be determined for a property, variable, or parameter then it is assigned the mixed type.
<?php
class MyClass
{
public MyOtherClass $withTypeDeclaration;
/** @var MyOtherClass **/
public $withTypeAnnotation
public function withTypeDeclarations(string $param): int { }
/**
* @param string $param
* @return int
*/
public function withTypeAnnotations($param) { }
}Variables can be annotated with a type if necessary. The annotation immediately preceeding an assignment overrides the assigned type. Subsequent assignments may change the type again.
<?php
/** @var callable $var */
$var = 'is_numeric'; //$var is callable instead of string
$var = 1; //$var is now an intIn addition to the standard PHPDoc type annotations Intelephense also supports generic type syntax for iterable and ArrayAccess types. For example:
Generator<KeyType, ElementType>ArrayAccess<string, ElementType>array<int, ElementType>
Union (TypeA|TypeB) and intersection (TypeA&TypeB) types are supported. Where both a type declaration and a type annotation is provided then the resulting type will be the intersection of the two. Types will be reduced where possible using the following rules.
SuperType|SubType=>SuperTypeSuperType&SubType=>SubType
Sometimes there may be type annotations in libraries or project files that do not accurately reflect the desired type. Intelephense offers compatibility settings to handle some common cases.
intelephense.compatibility.correctForBaseClassStaticUnionTypes
{
"type": "boolean",
"default": true,
"description": "Resolves `BaseClass|static` union types to `static` instead of `BaseClass`.",
"scope": "window"
}intelephense.compatibility.correctForArrayAccessArrayAndTraversableArrayUnionTypes
{
"type": "boolean",
"default": true,
"description": "Resolves `ArrayAccess` and `Traversable` implementations that are unionedwith a typed array to generic syntax. eg `ArrayAccessOrTraversable|ElementType[]` =>`ArrayAccessOrTraversable<mixed, ElementType>`.",
"scope": "window"
}You may also see several non standard types in hovers.
unset- the type given to variables that are undefined orunset().never- the type returned from a function that does not terminate normally (egdie()) or that represents an impossibility (added in PHP 8.1).
Intelephense aims to support all frameworks but does not implement framework specific solutions. Some frameworks are coded in a way that make it difficult to analyse. This may be because of lack of type declarations/annotations; heavy use of __get, __set, __call, __callStatic magic methods; or dynamic generation of class aliases at runtime.
Packages can be found online that aim to workaround these issues by providing stubs of symbols to help static analysers like Intelephense understand the code.
- Laravel - barryvdh/laravel-ide-helper