PHP VIM IDE
Background
Recently I am developing an app for Nextcloud, and it requires some PHP tool, usually, vscode is my go-to IDE/Editor for any small project. but I notice a drag on my 4 years old Dell-XPS laptop, so I decided to switch to vim. I have been a casual vim user, but this time I want to set up correctly, so here is how I do it:
Update: 2020-8-21 adding phan support: Setup vim with phan
Update: 2020-8-30 when php-language-server is initialized , it will scan the whole dirctory and if xdebug is enabled at the same time, it will take longer
Vim Components :
- vim-gtk with python3 support
- vim-plug as a plugin manager
- ALE as language protocol client
- PHP-language-server as a language server
- deoplete.nvim for auto-completion
- PHP-CS-Fixer for code standard compliance
- autoformat for code format(Mainly for indenting)
- vim-debug for code step by step debugging
Let’s start from an empty docker container to see how can we set it up
1 first install some basic tool
apt install git curl composer python3-pip
danny@xps:~$ docker run -i -t ubuntu /bin/bash
root@05ba32a655a8:/# apt update
Get:1 http://archive.ubuntu.com/ubuntu focal InRelease [265 kB]
.........
root@05ba32a655a8:/# apt install git curl composer python3-pip
Reading package lists... Done
Building dependency tree
2 Install vim-gtk
apt install vim-gtk
root@05ba32a655a8:/# apt install vim-gtk
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
......
we are installing vim-gtk instead of plain vim is we need the vim python3 support which is needed by vim-debug. To check if your vim support python3,issue the following command:
root@05ba32a655a8:/# vim --version
VIM - Vi IMproved 8.1 (2018 May 18, compiled Apr 15 2020 06:40:31)
Included patches: 1-2269
Modified by team+vim@tracker.debian.org
Compiled by team+vim@tracker.debian.org
Huge version with GTK3 GUI. Features included (+) or not (-):
+acl -farsi -mouse_sysmouse -tag_any_white
+arabic +file_in_path +mouse_urxvt +tcl
+autocmd +find_in_path +mouse_xterm +termguicolors
+autochdir +float +multi_byte +terminal
-autoservername +folding +multi_lang +terminfo
+balloon_eval -footer -mzscheme +termresponse
+balloon_eval_term +fork() +netbeans_intg +textobjects
+browse +gettext +num64 +textprop
++builtin_terms -hangul_input +packages +timers
+byte_offset +iconv +path_extra +title
+channel +insert_expand +perl +toolbar
+cindent +job +persistent_undo +user_commands
+clientserver +jumplist +postscript +vartabs
+clipboard +keymap +printer +vertsplit
+cmdline_compl +lambda +profile +virtualedit
+cmdline_hist +langmap -python +visual
+cmdline_info +libcall +python3 +visualextra
...
if you can see +python3, then you are good to go.
3 install vim-plug for an easier plugin installation
Go to https://github.com/junegunn/vim-plug to see how you can do it. we are using vim8 here, not neovim, so we will issue following command:
curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
root@05ba32a655a8:/# cd
root@05ba32a655a8:~# curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
> https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 80033 100 80033 0 0 77853 0 0:00:01 0:00:01 --:--:-- 77853
after installing vim-plug, we will set up the config for it in ~/.vimrc
call plug#begin('~/.vim/plugged')
call plug#end()
vim plugins will come between this two commnds
4 Install ALE
add Plug 'dense-analysis/ale'
between the two lines:
call plug#begin('~/.vim/plugged')
Plug 'dense-analysis/ale'
call plug#end()
close and open .vimrc
again and then type command PlugInstall
, ALE will be installed

5 install php-language-server
composer global require felixfbecker/language-server jetbrains/phpstorm-stubs:@dev
root@05ba32a655a8:~# composer global require felixfbecker/language-server jetbrains/phpstorm-stubs:@dev
Changed current directory to /root/.composer
Using version ^5.4 for felixfbecker/language-server
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 17 installs, 0 updates, 0 removals
- Installing symfony/polyfill-ctype (v1.18.1): Downloading (100%)
- Installing webmozart/assert (1.9.1): Downloading (100%)
- Installing webmozart/path-util (2.3.0): Downloading (100%)
- Installing webmozart/glob (4.1.0): Downloading (100%)
- Installing sabre/uri (2.2.0): Downloading (100%)
- Installing sabre/event (5.1.0): Downloading (100%)
- Installing psr/log (1.1.3): Downloading (100%)
- Installing phpdocumentor/reflection-common (2.2.0): Downloading (100%)
- Installing phpdocumentor/type-resolver (1.3.0): Downloading (100%)
- Installing phpdocumentor/reflection-docblock (4.3.4): Downloading (100%)
- Installing netresearch/jsonmapper (v1.6.0): Downloading (100%)
- Installing microsoft/tolerant-php-parser (v0.0.22): Downloading (100%)
- Installing jetbrains/phpstorm-stubs (dev-master 147255f): Cloning 147255f02e from cache
- Installing felixfbecker/language-server-protocol (v1.4.0): Downloading (100%)
- Installing felixfbecker/advanced-json-rpc (v3.1.1): Downloading (100%)
- Installing composer/xdebug-handler (1.4.2): Downloading (100%)
- Installing felixfbecker/language-server (v5.4.6): Downloading (100%)
Writing lock file
Generating autoload files
2 packages you are using are looking for funding.
Use the composer fund command to find out more!
Here we are using the global
config, so all the php modules will be installed in the user .composer
dir. As you can see from the composer output
Changed current directory to /root/.composer
on the github README, it does not mention the phpstrom-stubs, and you need to include it in the command, otherwise, you will get the following error:
composer global require felixfbecker/language-server
Changed current directory to /root/.composer
Using version ^5.4 for felixfbecker/language-server
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
- felixfbecker/language-server v5.4.6 requires jetbrains/phpstorm-stubs dev-master -> satisfiable by jetbrains/phpstorm-stubs[dev-master] but these conflict with your requirements or minimum-stability.
- felixfbecker/language-server v5.4.5 requires jetbrains/phpstorm-stubs dev-master -> satisfiable by jetbrains/phpstorm-stubs[dev-master] but these conflict with your requirements or minimum-stability.
- felixfbecker/language-server v5.4.4 requires jetbrains/phpstorm-stubs dev-master -> satisfiable by jetbrains/phpstorm-stubs[dev-master] but these conflict with your requirements or minimum-stability.
- felixfbecker/language-server v5.4.3 requires jetbrains/phpstorm-stubs dev-master -> satisfiable by jetbrains/phpstorm-stubs[dev-master] but these conflict with your requirements or minimum-stability.
- felixfbecker/language-server v5.4.2 requires jetbrains/phpstorm-stubs dev-master -> satisfiable by jetbrains/phpstorm-stubs[dev-master] but these conflict with your requirements or minimum-stability.
- felixfbecker/language-server v5.4.1 requires jetbrains/phpstorm-stubs dev-master -> satisfiable by jetbrains/phpstorm-stubs[dev-master] but these conflict with your requirements or minimum-stability.
- felixfbecker/language-server v5.4.0 requires jetbrains/phpstorm-stubs dev-master -> satisfiable by jetbrains/phpstorm-stubs[dev-master] but these conflict with your requirements or minimum-stability.
- Installation request for felixfbecker/language-server ^5.4 -> satisfiable by felixfbecker/language-server[v5.4.0, v5.4.1, v5.4.2, v5.4.3, v5.4.4, v5.4.5, v5.4.6].
Installation failed, deleting ./composer.json.
after installing the php-language-server, we need to generate the stubs for PHP
composer run-script --working-dir=/root/.composer/vendor/felixfbecker/language-server parse-stubs
root@05ba32a655a8:~# composer run-script --working-dir=/root/.composer/vendor/felixfbecker/language-server parse-stubs
> LanguageServer\ComposerScripts::parseStubs
......
Saving Index
Finished
root@05ba32a655a8:~#
now let’s configure php-language-server for ALE
call plug#begin('~/.vim/plugged')
Plug 'dense-analysis/ale'
call plug#end()
let g:ale_php_langserver_executable = '/root/.composer/vendor/bin/php-language-server.php'
let g:ale_linters = {'php': ['langserver']}

to see if the php-language-server is working or not, let’s create a simple PHP file to test, as you can see if we add invalid code or remove trailing ;
, we will get error and move to the error line, you can see the message displayed on the bottom, remove error, the error message and mark also disapper

6 Install deoplete.nvim
you can go to the github and choose the the plugins you need , since i am using vim8 , here is my .vimrc
config
call plug#begin('~/.vim/plugged')
Plug 'dense-analysis/ale'
Plug 'Shougo/deoplete.nvim'
Plug 'roxma/nvim-yarp'
Plug 'roxma/vim-hug-neovim-rpc'
call plug#end()
let g:ale_php_langserver_executable = '/root/.composer/vendor/bin/php-language-server.php'
let g:ale_linters = {'php': ['php', 'langserver']}
close and reopen .vimrc
, then same command to install the plugin PlugInstall

deoplete.nvim will also need pynvim
, let’s install it :
pip3 install pynvim
to enable deoplete.nvim, you need to add these two lines to .vimrc
let g:deoplete#enable_at_startup = 1
call deoplete#custom#source('ale', 'rank', 999)
and also set the .vimrc
encoding by adding :
set encoding=utf-8
the final one would be :
set encoding=utf-8
call plug#begin('~/.vim/plugged')
Plug 'dense-analysis/ale'
Plug 'Shougo/deoplete.nvim'
Plug 'roxma/nvim-yarp'
Plug 'roxma/vim-hug-neovim-rpc'
call plug#end()
let g:ale_php_langserver_executable = '/root/.composer/vendor/bin/php-language-server.php'
let g:ale_linters = {'php': ['php', 'langserver']}
let g:deoplete#enable_at_startup = 1
call deoplete#custom#source('ale', 'rank', 999)

7 Install PHP-CS-Fixer
php-cs-fixer will help you write standard compliance code , here is an brife introduction on youtube : How to auto format your code
add these two lines to your .vimrc
after installing php-cs-fixer by running composer global require friendsofphp/php-cs-fixer
let g:ale_fixers = {'php': ['php_cs_fixer'] }
let g:ale_php_cs_fixer_executable='/root/.composer/vendor/bin/php-cs-fixer'
let’s see how it works. on PHP standard , you should put {
of a function on a new line, php-cs-fixer can automatically correct this one for you

8 Install vim-debug
we will make another post on how to configure the vim-debug