Creating a custom debug configuration for PhpStorm

Hi,

I would like to add a custom configuration, based on PhpStorm Xdebug. Could you please advise me from where I should start?

7 comments
Comment actions Permalink

Could you please explain what you want to achieve, how is it different than builtin Debug config, do you want to extend existing with new functionality or create something completely different, ...

0
Comment actions Permalink

I would like to do two things:

 

1. quite often we have to create a separated configuration for a task, it includes:

- host name

- path mapping

- Xdebug port connection

 

So, I would like to make a kinda template: you choose a task, and get the debug-configuration.

 

2. Another thing, I guess would be trickier.

We use Soft Mocks for unit-tests. Which is rewriting files before execution so that it became impossible to debug, as soon as real executed paths are different from project. I wish to make a "dynamic path-mapper" to get it debuggable

0
Comment actions Permalink

Could you please describe the use case for this Xdebug configuration in a little more details? Why wouldn't simple Listening for incoming connections do the trick?
Since the hostnames are different, you can keep as many server mappings as you need.
Or is it because the Xdebug port is different each time?

0
Comment actions Permalink

@Yann, this is better than nothing but I'm afraid it doesn't solve anything: as soon as I should have many path mappings, I will have to have many server-names (the number is not limited). And it doesn't solve the issue with Xdebug port

@Eugene, what do you mean "Listening for connections"?

Actually, there hostname as well as path mapping is dynamic, so I can't just pre-define set of servers and re-use them later on. And yes, I have the issue with Xdebug port.

And I believe there is no standard solution for "Soft-mock" case.

0
Comment actions Permalink

@Mikhail, "Listen for debug connection" is an action in PhpStorm which starts listening for all incoming Xdebug connections on port configured in `Settings | Languages & Frameworks | PHP | Debug` -> `Xdebug | Debug port`. If you use this action, you can start debug session from the browser. There's no need to create a php server with mapping, it will be created automatically. This will work out of the box if path mappings are simple, e.g. <local root> -> <remote root>.
https://www.jetbrains.com/help/phpstorm/zero-configuration-debugging.html

Unfortunately it won't help you if path mappings are generated dynamically or are constantly changing. In this case, you can create a plugin with PHP run-configuration. You'll need to implement and register in XML `com.intellij.execution.runners.ProgramRunner`, debug session should be configured and started in `com.intellij.execution.runners.ProgramRunner#execute(com.intellij.execution.runners.ExecutionEnvironment)`.
To make it easier, you can inherit `com.jetbrains.php.run.PhpDebugRunner`, its not in public API and we can't guarantee it won't change in the future but we'll try our best to notify you if we decide to deprecate or change this class.

To start debug session, you should create/find `com.jetbrains.php.config.servers.PhpServer` and set/update path mappings. You can specify which Xdebug port should be used as a second parameter in `com.jetbrains.php.debug.xdebug.XdebugExtension#startDebugServer(com.intellij.openapi.project.Project, int)`. The implementation is not trivial, feel free to ask more questions.

Here are general documentation about run-configurations: http://www.jetbrains.org/intellij/sdk/docs/basics/run_configurations.html

0
Comment actions Permalink

@Svetlana, thank you for the advice.

 

I was able get custom path mapping by implementing own `com.jetbrains.php.config.servers.PhpServer` class

@Tag("shot-server")
class ShotServer : PhpServer
{
// Default constructor is used by XML serialisation
constructor() {
PhpServer()
}

constructor(urlComponents: UrlComponents, project : Project) {
PhpServer()

setHost(urlComponents.host)
name = mkServerName(urlComponents.host)
isUsePathMappings = true
mappings = makeMappings(project, urlComponents)
}

companion object {
fun mkServerName(hostName:String): String {
return "shot-debug:$hostName"
}

private fun makeMappings(project : Project, urlComponents: UrlComponents): MutableList<PathMappingSettings.PathMapping> {
val mappings = arrayListOf<PathMappingSettings.PathMapping>()

val roots = ProjectRootManager.getInstance(project).contentRootUrls
if (roots.isEmpty()) {
return mappings.toMutableList()
}

val projectRoot = roots[0].replace("file://", "")

mappings.add(PathMappingSettings.PathMapping(projectRoot, "/local/deploy/shot/${urlComponents.shotName}")) // shotName

return mappings.toMutableList()
}
}
}


And to start a debug session on a my own port by creating XdebugServer when it needs:

private lateinit var manager: XdebugServerConnectionManager

private fun startXdebugConnection(): XdebugServer {
manager = XdebugServerConnectionManager()
return manager.start(9050)
}
0

Please sign in to leave a comment.