Execute custom php to manage click2call I need to POST to a url with php code in order to make a phone call. This is an example of javascript:

&lt;script&gt;
        function callme() {
            var XHR = new XMLHttpRequest();
            XHR.addEventListener('readystatechange', function() {
                if (XHR.readyState == 4 &amp;&amp; XHR.status == 200) {
                    document.getElementById("result").innerHTML = XHR.responseText;
                } else {
                    document.getElementById("result").innerHTML = "ha ocurrido un error: " + XHR.responseText
                }
            });

            var FD  = new FormData();
            FD.append('number', document.getElementById("number").value);
            XHR.open('POST', 'doC2c.php');
            document.getElementById("result").innerHTML = "calling ..."
            XHR.send(FD);
        }
    &lt;/script&gt;


And the doC2c.php file must be:

&lt;?php

$apikey = ""; //API KEY MUST BE PUT HERE GOT FROM DB
$origin = ""; //ORIGIN EXT MUST BE PUT HERE OR GET FROM SOMEWHERE
if ($apikey == "") {
    header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
    echo "APIKEY MISSING";
    die();
} else if ($origin == "") {
    header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
    echo "ORIGIN MISSING";
    die();
} else {
    $opts = array(
       'http' =&gt; array(
           'method' =&gt; "GET",
           'header' =&gt; "Content-type: application/json\n"
                       ."X-Api-Key: ".$apikey,
       )
    );

    $context = stream_context_create($opts);
    $response = file_get_contents("https://....../api/originatecall/".$origin."/".$_POST['number'], false, $context);

    //echo $response;
    echo "CALLING...";
}
?&gt;


I would like to make a D8 module that create a URL I could POST to execute the php code, but I want to have Drupal API to query de DB and so on. I know how to make a module with a form and a route to show it, but I don't know how assign a route to a php code file.
A route is a path which is defined for Drupal to return some sort of
  content on


source: Routing system overview

You can think of it like this, a route creates a url that displays a page. This route has a controller which executes the function/method that is in the controller class.

my_module/my_module.routing.yml

my_module.content:
  path: '/fetch'
  defaults:
    _controller: '\Drupal\my_module\Controller\DoC2cController::content'
    _title: 'Hello World'
  requirements:
    _permission: 'access content'


In the example above when you go to /fetch it will execute the content() method that is inside the DoC2cController class php file. This method must return a render array.

For more in depth info read Structure of routes.

my_module/src/Controller/DoC2cController.php

&lt;?php

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Form\drupal_set_message;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Defines HelloController class.
 */
class DoC2cController extends ControllerBase {

  /**
   * Display the markup.
   *
   * @return array
   *   Return markup array.
   */
  public function content() {

    $apikey = ""; //API KEY MUST BE PUT HERE GOT FROM DB
    $origin = ""; //ORIGIN EXT MUST BE PUT HERE OR GET FROM SOMEWHERE
    if ($apikey == "") {
        drupal_set_message(t('APIKEY MISSING'), 'error');
        throw new NotFoundHttpException();
    } else if ($origin == "") {
        drupal_set_message(t('ORIGIN MISSING'), 'error');
        throw new NotFoundHttpException();
    } else {
        $opts = array(
           'http' =&gt; array(
               'method' =&gt; "GET",
               'header' =&gt; "Content-type: application/json\n"
                           ."X-Api-Key: ".$apikey,
           )
        );

        $context = stream_context_create($opts);
        $response = file_get_contents("https://....../api/originatecall/".$origin."/".$_POST['number'], false, $context);

        //echo $response;
        $response = "CALLING...";
    }

    // Make response string translatable
    $translatable_response = new TranslatableMarkup("@reponse", [
      '@response' =&gt; $response,
    ]);

    return [
      '#type' =&gt; 'markup',
      '#markup' =&gt; $translatable_response,
    ];
  }

}