10
Migrating from PHPStorm to Cursor
Let's explore how to configure familiar JetBrains PHPStorm functions in Cursor (VS Code). Many of the features described in this article are general and not specifically tied to PHP, so it will be relevant for migration from other JetBrains products as well.
Nevertheless, we'll set up full PHP support, xdebug, .env, yaml, symfony, git, transfer hotkeys and theme, understand how to connect to databases and remote servers. There will be a brief personal comparison of IDEs. We'll barely touch on Cursor's functions.
Introduction
Very briefly about Cursor – it's an "AI code editor" as stated on the official website. In fact, it's a fork of VS Code that provides a well-thought-out integration of AI tools into the IDE.
Cursor has broader AI assistant capabilities:
- can create files;
- can edit files and highlight multiple changes in the editor;
- works in terminal: you can generate bash commands or get explanations for console errors in one click.
Actually, I'm switching precisely for the AI features. JetBrains' AI Assistant in my experience significantly lags behind Cursor in terms of quality and capabilities, while alternative plugins (Github Copilot, Codeium, etc.) are almost universally limited to just chat and plain text suggestions.
And a small disclaimer: I use Ubuntu and English interface language, so all hotkeys and commands (there won't be many) will be specified for these.
TL;DR; - install plugins from the list below and copy the config from the end of the article to your settings.json
.
The article turned out to be quite lengthy, so here's a table of contents:
- Plugins
- Config
- Appearance
- General Points
- PHP
- Git
- Docker
- Debug
- Remote Server Connection
- Database Connection
- Pricing
- Conclusions
Plugins
You'll need plugins for full functionality. You can install them either through GUI by finding them in the File > Preferences > Extensions
menu, or through the installation command in the quick commands panel (Ctrl + Shift + P):
- PHP Tools for VS Code - full language support, formatting, debug, PHPDoc, without this plugin (or a combination of similar ones) VS Code works with php at the level of a notepad with syntax highlighting. Installation also adds Composer, PHP Profiler, and IntelliPHP - AI Autocomplete for PHP plugins in preview mode, you can get rid of the latter right away since we're using Cursor (delete or disable). Unfortunately, some plugin features are paid - not only AI features but also, for example, adding getters/setters or namespace auto-import - things that come out of the box in PHPStorm.
- Symfony for VSCode - basic symfony container support and tracking changes in configs for its update, service name suggestions. Actually, it's very far in functionality from the PHPStorm plugin (Symfony Support). For me, even basic navigation from
services.yaml
to class doesn't work, and there's no very convenient feature of importing service into current class - when mentioning a service class in code that's absent in the current class - the JetBrains plugin can search by variable name and add to constructor in 1 click. Also, there's no route search, for example (works in PHPStorm through quick search). - YAML - yaml support.
- DotENV - .env support.
- GitLens — Git supercharged - extended git support - blame, commit graph, and much more.
- SQLTools, (and drivers - MySQL / MariaDB / TiDB, MS SQL, PostgreSQL) - DB manager, drivers are implemented as child plugins.
- IntelliJ IDEA Keybindings - familiar hotkeys that don't always perform exactly the same function. Shift + Shift, for example, is file search, in PHPStorm the quick search window functionality is much broader (search immediately by file names, in files themselves, search for class/function/variable names, IDE settings, and much more).
- JetBrains Icon Theme - familiar folder/file icons.
- Docker - plugin for managing docker containers in GUI.
- Markdown Preview Enhanced - markdown syntax highlighting and readonly preview.
- SFTP - file synchronization with remote server.
- Darcula Contrast - dark theme from PHPStorm.
There are also plugin collections, for example PHP Language Essential Extension Pack, Symfony extensions pack, or Laravel Extension Pack. I still don't recommend installing everything in bulk.
VS Code Config
Here and further by config we mean the settings.json
file, which lies in ~/.config/Cursor/User/settings.json
for user-level settings and in .vscode/settings.json
at project level.
You don't need to remember the paths to configs, just find Preferences: Open User|Project settings
in the command panel (Ctrl + Shift + P) depending on whether you need global settings or for a specific project.
VS Code has an extended json that allows comments and commas at the end of enumerations. Part of the config and command panel:
Also, editor settings (editor.*
) can be bound to a specific environment by placing them in a specific key, for example, in the [php]: {}
section you can specify settings that will only work for php.
Appearance
I'll show as a target the PHPStorm design that I've been using for many years (Darcula contrast):
And also Cursor (VS Code) right after installation with dark theme, to understand what we have out of the box:
Window Title
Cursor window title out of the box:
This really catches the eye in Ubuntu - the window title is duplicated, showing the standard system one and below it the functional title from VS Code, which also duplicates the minimize, maximize, and close window buttons.
Fortunately, it can be disabled through config:
{
"window.titleBarStyle": "custom"
}
After changing this variable's value, you need to restart the IDE completely. Title after changes:
Theme
You can change the theme in the File > Preferences > Theme > Color Theme
menu or with the Ctrl + ` hotkey. By default, the most popular ones are pre-installed, for example, Monokai is already in the list.
I use the darcula contrast theme in PHPStorm - by default, VS Code doesn't have it, but you can find it in the marketplace - darcula contrast. Install according to the instructions at the link:
Ctrl + Shift + P > ext install nashpatty.darculacontrast
.
If you like another theme - you can also search for it in the marketplace, it's likely to be there. In the worst case, you can configure everything manually through config.
You can also fine-tune colors to your taste, I wasn't quite satisfied with the colors in the ready-made scheme, so I adjusted them to what actually appears in my PHPStorm:
{
"workbench.colorTheme": "Darcula Contrast",
"editor.fontSize": 13,
"terminal.integrated.fontSize": 14,
"debug.console.fontSize": 14,
"workbench.tree.indent": 20,
"workbench.iconTheme": "vscode-jetbrains-icon-theme-2023-dark",
"workbench.colorCustomizations": {
"sideBar.background": "#2b2d30",
"sideBarSectionHeader.background": "#2b2d30",
"sideBarSectionHeader.border":"#1e1f22",
"editor.background": "#1e1f22",
"titleBar.activeBackground": "#2b2d30",
"statusBar.background": "#2b2d30",
"activityBar.background": "#2b2d30",
"activityBar.border":"#1e1f22",
"panel.background":"#2b2d30",
"panel.border": "#1e1f22"
}
}
A complete description of all keys can be found in the documentation, you can customize it to your liking. Before > after:
File Structure
By default, horizontal indents are quite small. Folder icons are missing, icons on all php files are the same and not readable - in the form of a small purple elephant.
We fix indents and enable icons if you haven't enabled them when installing the plugin (settings.json
):
{
"workbench.tree.indent": 20,
"workbench.iconTheme": "vscode-jetbrains-icon-theme-2023-dark"
}
Differences
- All php files will have the same icon, there's no separation into classes / interfaces / traits and other types like in PHPStorm. You can join the issue on the plugin's github if you want them to appear.
- You also can't change the font size for the file structure separately. You can join this issue in VS Code.
Before > after:
Panel Layout
Overall everything is similar here, the only thing - by default the terminal panel is "squeezed" between the left and right panels, while in PHPStorm it's aligned to screen width.
Couldn't find how to edit this through config, but you can change alignment as follows:
Ctrl + Shift + P > View: Set Panel Alignment to Justify
.
You can also choose ... Left
/ ... Right
, then the terminal panel will occupy the central and left / right part of the screen respectively.
Opening Multiple Projects
In PHPStorm, when you open a new project - the IDE asks if you want to open it in a new window or in the current one. VS Code doesn't have this, the project when opened through the File
menu always opens in the current window by default. This can be inconvenient if you, like me, want to work with multiple projects simultaneously.
Therefore, config comes to help again:
{
"window.openFoldersInNewWindow": "on"
}
You can set either always in a new window or always in the old one, VS Code can't ask. This PHPStorm panel when switching between projects is missing:
Vertical Menu
As far as I understand, it's out of the box in VS Code, but for Cursor you need to add one more option to config:
{
"workbench.activityBar.orientation": "vertical"
}
Before > after:
General Points
Autosave
By default, VS Code doesn't automatically save changes from a file - this is enabled separately in config (settings.json
):
{
"files.autoSave": "onFocusChange"
}
onFocusChange
- enables autosave of files when the editor tab loses focus - allows saving changes to the current file when switching to terminal to run some console checks (this makes it more convenient for me thanafterDelay
, which saves changes once in a certain period and is recommended by default).
Detailed information about autosave can be found in the documentation.
File Watching Tuning
If besides the interface you work in console or files in your project can change from another source - it's useful to make adjustments to the file change tracking mechanism (same settings.json
):
{
"files.autoGuessEncoding": true,
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/node_modules/**": true,
"**/var/**": true,
"**/cache/**": true
}
}
autoGuessEncoding
- allows VS Code to guess file encoding when opening;watcherExclude
- disables specified folders and files from tracking.
Auto-closing Files
By default, VS Code closes a file if you opened it for preview (single click on file). I.e., you go to the file structure, open a class file to look at some code there, then open another file to read something there - VS Code closes the previously opened file. At the same time, it honestly hints in the tab name with italics that this tab is opened temporarily and will be closed at the first opportunity. Moreover, the temporary tab always opens to the right of the current window, so the order of tabs is constantly changing.
However, if you open a file with a double click - everything is ok, it opens for editing and remains working.
The behavior is probably useful but completely unfamiliar. Fortunately, it can be disabled, and at the same time make file opening only by double click (single click will just highlight the file in the list):
{
"workbench.editor.enablePreview": true,
"workbench.list.openMode": "doubleClick"
}
Differences
- There's no complete analog of the quick search panel (by classes / file names / routes / functions etc.) that opens with Shift + Shift in PHPStorm, only separate types of search by content and file names:
PHP
Variable Highlighting
VS Code by default considers $
a separator symbol, so we change the set of such separators in config so that when double-clicking a variable, the dollar is also selected:
{
"editor.wordSeparators": "`~!@#%^&*()-=+[{]}\\|;:'\",.<>/?"
}
Linter - Syntax Check
The default php linter is system-wide, you can check version and settings by calling php -v
in console.
If the binary for some reason lies elsewhere - you can specify the path in settings (settings.json
):
{
"php.validate.executablePath": "/usr/bin/php8.3"
}
Detailed instructions can be found in the official docs.
If you don't want syntax analysis to highlight errors from ignored files (specified in .gitignore
), you also need to enable this option in config (settings.json
):
{
"php.problems.excludeGitIgnore": true
}
Git
Git panel in PHPStorm:
GitLens panel in VS Code:
Out of the box, VS Code has a Source Control tab with minimal functionality (view changes, brief commit graph). You can extend this functionality to familiar with the GitLens plugin. In general terms - everything is very close to what we have in PHPStorm. List of branches, viewing changes by commits, commit graph.
Merge
Conflict resolution happens in the so-called Merge editor - in my opinion, the PHPStorm variant is more convenient and intuitively understandable.
In VS Code, you need to open the Source Control tab in the panel - there will be a list of all changed files, conflicting ones are displayed at the top of the list - after opening them you can launch the Merge editor.
The conflict state is more clearly visible in PHPStorm:
But resolving the conflict right from editing will only be possible manually, there's no highlighting. The conflict resolution interface in PHPStorm is like this:
In VS Code, you can only see the conflict by switching to the Source Control tab, from the file opened for editing you can resolve the conflict right away:
The Merge editor looks similar to PHPStorm, but from a UX perspective there are noticeable differences:
Differences
- In PHPStorm, the conflict state is explicitly displayed in the window title as a separate button, which immediately opens a window with all conflicting files and the ability to resolve conflicts.
- The merge process itself is more understandable for me in PHPStorm in terms of UX due to intuitively clear arrows and Left/Right terms instead of Current/Incoming in VS Code, and also because only conflicts are highlighted. VS Code also highlights non-conflicting changes in common code - at first it wasn't clear at all that in the screenshot below the first highlighted block was already resolved:
- You can't view changes from multiple commits at once (PHPStorm allows selecting multiple commits and aggregating all changes, as well as performing mass actions - sequential cherry-pick / revert / etc., in VS Code you can select only 1 commit):
- When creating a new file - it's not marked as added to git by default and there's no such request (most likely can be configured in GitLens).
- No ability to generate commit description (AI Assistant in PHPStorm can do this).
Docker
Docker panel VS Code:
The Docker plugin shows a list of containers, images, networks, storages and generally provides a full interface for management. You can also quickly connect to container logs, launch shell, view files inside the container or delete an image. I'm more used to working with docker in console, so I rarely use GUI.
If comparing superficially with PHPStorm - about the same thing. Docker panel PHPStorm:
Debug
Namely xdebug. The needed plugin was already installed along with the main PHP plugin, just need to configure it.
In the actions menu there's a separate Run and Debug section - you just need to configure your configuration there. This is also done through json config, which is pre-filled by default. I have the project deployed locally in docker, additionally I only needed to specify directory mapping (launch.json
):
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug with Xdebug",
"type": "php",
"request": "launch",
"port": 9003,
"pathMappings": {
"/var/www/site": "${workspaceRoot}"
}
}
]
}
Debug panel VS Code:
In other aspects, the debug process is similar to PHPStorm (logically, the engine is the same). It's worth noting perhaps that the VS Code plugin provides a built-in server for running scripts with built-in debugger out of the box, if that's relevant for you - the start threshold should be lower here, no need to configure xDebug itself, personally I haven't tested this mode.
Debug panel PHPStorm:
Remote Server Connection
Auto-deploying code to your remote site is a fairly common way of development.
And VS Code has a special approach here. Most guides about remote development through VS Code describe using the Remote - SSH plugin, which installs VS Code Server on the server side, and locally there's actually only UI left. The server requires ~2 Gb RAM and a 2-core processor, and if you have one server set up in your company for several sites and several developers - this VS Code Server will very quickly eat up its resources (we've had this happen repeatedly in practice).
We'll go the simple way, through the SFTP plugin.
Install the plugin, add config with the SFTP: config
command (call command menu - Ctrl + Shift + P).
{
"name": "dev server",
"host": "192.168.0.2",
"protocol": "sftp",
"port": 22,
"username": "user",
"remotePath": "/var/www/mysite.ru/src",
"uploadOnSave": true,
"useTempFile": false,
"openSsh": false,
"privateKeyPath": "/home/ubuntu/.ssh/id_rsa",
"ignore": [".vscode", ".git", ".DS_Store", ".env", "vendor"]
}
Then when entering "SFTP" in the command menu you can see the full list of possibilities, from the most relevant and frequently used:
View: Show SFTP
- opens remote server file structure;SFTP: Sync Local > Remote
(and vice versa) - synchronize files with server in one direction or another;Upload Active File | Folder | Project
- upload current file / folder / entire project to server.
SFTP commands VS Code:
Database Connection
IDE is not only about code, you can view data, table structure of DB, execute direct queries and in general in PHPStorm it's almost a full-fledged DB manager.
Database panel PHPStorm:
In VS Code, SQLTools plugin is responsible for working with DB. After its installation, a tab of the same name appears in the left sidebar - there you can create a connection for all types of DB whose drivers you installed with separate plugins. SQLTools panel VS Code:
Differences
- No through filtering / sorting of data by columns - quick filter and sorting only work for the current loaded page. You can verify this from the screenshots - in both IDEs sorting by ID descending is set.
- At the server connection level, you can't limit the list of displayed databases (at least through interface) - all databases to which there are rights with specified accesses are displayed (in PHPStorm such possibility exists in the connection settings interface).
- AI Assistant in JetBrains within SQL query work can send database schema as context, so SQL query built from text request will with high probability be structurally correct. Within Cursor only autocompletion works, it figures out database structure itself. VS Code query history:
- VS Code has SQL query history.
Pricing
Let's also compare prices for individual use.
PHPStorm
- PHPStorm - 99$ / 79$ / 59$ (or euros depending on country) for 1/2/3+ year of use or 9.9$ per month;
- full php support - free out of the box, at better level than in VS Code with paid plugin;
- GitHub Copilot - 100$ per year or 10$ per month;
- (alternative) JetBrains AI Assistant - 100$ per year or 10$ per month.
In total comes to 13-20$ depending on plan.
Cursor
- Cursor - 192$ per year or 20$ per month;
- PHP Tools for Visual Studio Code - 79$ / 49$ for 1/2+ year of use, no monthly tariff.
In total comes to 20-27$ per month depending on plan.
Conclusions
In the end, personally for me Cursor's AI features outweighed the difference in cost and functionality of VS Code in conjunction with PHP. All other differences turned out to be either insignificant or were eliminated within this article.
I also provide all the config we've gathered here:
{
"[php]": {
},
"php.validate.executablePath": "/usr/bin/php8.3",
/** >>> files **/
"files.autoSave": "onFocusChange",
"files.autoGuessEncoding": true,
"files.watcherExclude": {
"**/.git/**": true,
"**/node_modules/**": true,
"**/var/**": true,
"**/cache/**": true,
},
"php.problems.excludeGitIgnore": true,
/** <<< files **/
/** >>> theme settings **/
"workbench.colorTheme": "Darcula Contrast",
"editor.fontSize": 13,
"terminal.integrated.fontSize": 14,
"debug.console.fontSize": 14,
"workbench.tree.indent": 20,
"workbench.iconTheme": "vscode-jetbrains-icon-theme-2023-dark",
"workbench.colorCustomizations": {
"sideBar.background": "#2b2d30",
"sideBarSectionHeader.background": "#2b2d30",
"sideBarSectionHeader.border":"#1e1f22",
"editor.background": "#1e1f22",
"titleBar.activeBackground": "#2b2d30",
"statusBar.background": "#2b2d30",
"activityBar.background": "#2b2d30",
"activityBar.border":"#1e1f22",
"panel.background":"#2b2d30",
"panel.border": "#1e1f22"
},
/** <<< theme settings **/
/** >>> window **/
"window.commandCenter": true,
"window.customTitleBarVisibility": "auto",
"window.titleBarStyle": "custom",
"window.openFoldersInNewWindow": "on",
"workbench.activityBar.orientation": "vertical",
/** <<< window **/
/** >>> behavior **/
"workbench.editor.enablePreview": false,
"editor.wordSeparators": "`~!@#%^&*()-=+[{]}\\|;:'\",.<>/?",
"workbench.list.openMode": "doubleClick",
"redhat.telemetry.enabled": false,
"gitlens.currentLine.enabled": false,
"symfony-vscode.consolePath": "bin/console",
"explorer.confirmDelete": false,
/** <<< behavior **/
}
No comments yet
-
Hidden Disc Holder
Looking for a place to store your disc collection, and find shelf storage borin… -
Student48
For LSTU Computer Science graduates of 2014-2021, this name means a lot - let's… -
Migrating from PHPStorm to Cursor
Let's explore how to configure familiar JetBrains PHPStorm functions in Cursor… -
Stairway to Heaven: Customizing WLED
From the idea and attempts to use the standard firmware to building my own with… -
Training a Flux Character LoRA on Civitai
So, you want to create a LoRA for generating images of a specific person - here… -
My Music AI Album Release
Yesterday, I released my electronic music album on SoundCloud. The genres are…