FAQ
Hi internals.

I really hope that in the future PHP 7, there will be new server API.
May be you interested to know about them, here is the link, I am not
the author of development:
https://github.com/unbit/uwsgi-phpsgi/

But the problem is that in PHP there are no standards for such interfaces.
Now it is implemented like this:

<?php

function application($env)
{
  return ['200 OK', ['Content-Type' => 'text/plain'], 'Hello, world!'];
}

?>

I think this is a good opportunity to review the old interface ($_GET,
$_POST, ...) and start using the API internal HTTP module.

This all breaks backward compatibility, not $_GET, $_POST, ...
But this WSGI SAPI will used only new PHP code (not PHP legacy base).

This is a good opportunity to create something new and not be backward
compatible.

What do you think about this?

Search Discussions

  • Rowan Collins at Feb 8, 2015 at 11:48 pm

    On 08/02/2015 22:48, S.A.N wrote:
    Hi internals.

    I really hope that in the future PHP 7, there will be new server API.
    May be you interested to know about them, here is the link, I am not
    the author of development:
    https://github.com/unbit/uwsgi-phpsgi/

    But the problem is that in PHP there are no standards for such interfaces.
    Now it is implemented like this:

    <?php

    function application($env)
    {
    return ['200 OK', ['Content-Type' => 'text/plain'], 'Hello, world!'];
    }

    ?>

    I think this is a good opportunity to review the old interface ($_GET,
    $_POST, ...) and start using the API internal HTTP module.

    This all breaks backward compatibility, not $_GET, $_POST, ...
    But this WSGI SAPI will used only new PHP code (not PHP legacy base).

    This is a good opportunity to create something new and not be backward
    compatible.

    What do you think about this?
    The problem with creating an event-based API for PHP is that you don't
    just have to rethink superglobals, you have to rethink absolutely
    everything that currently acts as global state:

    - global variables
    - static variables within functions
    - class static variables
    - dynamic settings (ini_set etc)
    - globally registered callbacks (set_error_handler,
    spl_autoload_register, etc)
    - the counters of include_once() and require_once()
    - any function which implicitly fetches data based on some previous
    action (e.g. libxml_get_errors)

    If the language is not itself multi-threaded, all of these become
    arbitrarily shared once per thread the server spins up and reuses. If it
    *is* multi-threaded, you have another set of headaches about how both
    the engine and the userland can share and synchronize.

    Not that I don't like the idea, but it's a huge project, with potential
    for profoundly affecting the language.

    Regards,

    --
    Rowan Collins
    [IMSoP]
  • S.A.N at Feb 9, 2015 at 12:02 am

    2015-02-09 1:48 GMT+02:00 Rowan Collins <rowan.collins@gmail.com>:
    On 08/02/2015 22:48, S.A.N wrote:

    Hi internals.

    I really hope that in the future PHP 7, there will be new server API.
    May be you interested to know about them, here is the link, I am not
    the author of development:
    https://github.com/unbit/uwsgi-phpsgi/

    But the problem is that in PHP there are no standards for such interfaces.
    Now it is implemented like this:

    <?php

    function application($env)
    {
    return ['200 OK', ['Content-Type' => 'text/plain'], 'Hello, world!'];
    }

    ?>

    I think this is a good opportunity to review the old interface ($_GET,
    $_POST, ...) and start using the API internal HTTP module.

    This all breaks backward compatibility, not $_GET, $_POST, ...
    But this WSGI SAPI will used only new PHP code (not PHP legacy base).

    This is a good opportunity to create something new and not be backward
    compatible.

    What do you think about this?

    The problem with creating an event-based API for PHP is that you don't just
    have to rethink superglobals, you have to rethink absolutely everything that
    currently acts as global state:

    - global variables
    - static variables within functions
    - class static variables
    - dynamic settings (ini_set etc)
    - globally registered callbacks (set_error_handler, spl_autoload_register,
    etc)
    - the counters of include_once() and require_once()
    - any function which implicitly fetches data based on some previous action
    (e.g. libxml_get_errors)

    If the language is not itself multi-threaded, all of these become
    arbitrarily shared once per thread the server spins up and reuses. If it
    *is* multi-threaded, you have another set of headaches about how both the
    engine and the userland can share and synchronize.

    Not that I don't like the idea, but it's a huge project, with potential for
    profoundly affecting the language.

    Regards,

    --
    Rowan Collins
    [IMSoP]


    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    You're right, but there is no threading issues.
    One worker synchronously execute requests, but may run parallel many workers.
  • Rowan Collins at Feb 9, 2015 at 12:26 am

    On 09/02/2015 00:02, S.A.N wrote:
    You're right, but there is no threading issues.
    One worker synchronously execute requests, but may run parallel many workers.
    I'm not sure what you mean by this. I can see 3 ways of handling
    incoming web requests, as it affects PHP's threading:

    A) The current "shared nothing" model: the web server may have multiple
    processes or threads, but each requested is executed in a completely
    separate global scope of PHP.
    B) Each process or thread in the web server spawns an instance of the
    application; the application has a global state within that instance,
    and startup and shutdown code; the instance is sent multiple requests,
    but has no way to know if it is getting all the requests, half the
    requests, or one hundredth of the requests.
    C) The web server executes the application once, which sets up its
    global state, and then spawns an internal threading model; each request
    is sent to a worker thread within PHP, which has to synchronise with
    other threads in order to access any aspect of global state.

    I guess you are suggesting option (B), which is what I was referring to
    when I said that global state would be "arbitrarily shared" - if
    handling a particular request caused any global state to be changed,
    such as registering an error handler, it could affect anything from 0 to
    100% of subsequent requests, depending on how the web server is configured.

    The code therefore needs to avoid relying on any such global state at
    all, which basically restricts you to a subset of the current language.
    For it to become the default way of running PHP, huge changes would be
    needed to adapt code to this new model.

    The reason I mentioned threading is that under option (C), migration
    becomes a bit easier in some ways: you can move some things which are
    currently global state into an explicitly per-thread state, allowing old
    behaviour to be emulated; and you can leave other things in synchronized
    global state, like ini settings, solving the problem of "50% of my
    threads have a different error handler registered".

    Regards,

    --
    Rowan Collins
    [IMSoP]
  • S.A.N at Feb 9, 2015 at 2:16 am

    2015-02-09 2:26 GMT+02:00 Rowan Collins <rowan.collins@gmail.com>:
    On 09/02/2015 00:02, S.A.N wrote:

    You're right, but there is no threading issues.
    One worker synchronously execute requests, but may run parallel many
    workers.

    I'm not sure what you mean by this. I can see 3 ways of handling incoming
    web requests, as it affects PHP's threading:

    A) The current "shared nothing" model: the web server may have multiple
    processes or threads, but each requested is executed in a completely
    separate global scope of PHP.
    B) Each process or thread in the web server spawns an instance of the
    application; the application has a global state within that instance, and
    startup and shutdown code; the instance is sent multiple requests, but has
    no way to know if it is getting all the requests, half the requests, or one
    hundredth of the requests.
    C) The web server executes the application once, which sets up its global
    state, and then spawns an internal threading model; each request is sent to
    a worker thread within PHP, which has to synchronise with other threads in
    order to access any aspect of global state.

    I guess you are suggesting option (B), which is what I was referring to when
    I said that global state would be "arbitrarily shared" - if handling a
    particular request caused any global state to be changed, such as
    registering an error handler, it could affect anything from 0 to 100% of
    subsequent requests, depending on how the web server is configured.

    The code therefore needs to avoid relying on any such global state at all,
    which basically restricts you to a subset of the current language. For it to
    become the default way of running PHP, huge changes would be needed to adapt
    code to this new model.

    The reason I mentioned threading is that under option (C), migration becomes
    a bit easier in some ways: you can move some things which are currently
    global state into an explicitly per-thread state, allowing old behaviour to
    be emulated; and you can leave other things in synchronized global state,
    like ini settings, solving the problem of "50% of my threads have a
    different error handler registered".


    Regards,

    --
    Rowan Collins
    [IMSoP]


    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    Yes, option (B) is more like.

    Let me show in your PHP code, how the option that I like, we have the
    actual application work that way in the pecl-event module, we are
    satisfied, it is convenient and very fast for PHP.

    This is a very rough and simplified code:
    <?php

    class App
    {
         public static $db; // Persistent open connection to database
         public static $redis; // Persistent open connection to Redis
         public static $cache; // Persistent cache application

         public $request;
         public $response;
         public $session;

         public function __construct(HTTP $object)
         {
             $this->request = $object->request;
             $this->response = $object->response;
         }

         public function open()
         {
             /*
                Routing by $this->request, may be auth and open
    $this->session (analog $_SESSION), or throw Exception.
             */

             return $this;
         }

         public function run()
         {
             /*
                Run your business logic...
             */

             return $this;
         }

         public function close()
         {
             /*
                Run finally logic, and cleaning output buffer
             */

             $this->response->body = ob_get_clean();

             return $this;
         }

         public static function init()
         {
             /*
                Application configuration as static class state
             */

             ob_start();
             set_error_handler(/*...*/);

             self::$db = new DBConnection;
             self::$redis = new Redis;
             self::$cache = new Cache;
         }
    }

    // Bootstrap, run configuration
    App::init();

    // Handler WSGI (not multi-thread)
    function application(HTTP $object)
    {
         $app = new App($object);

         $app->open()->run()->close();

         return
         [
             $app->response->code,
             $app->response->headers,
             $app->response->body
         ];
    }

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupphp-internals @
categoriesphp
postedFeb 8, '15 at 10:48p
activeFeb 9, '15 at 2:16a
posts5
users2
websitephp.net

2 users in discussion

S.A.N: 3 posts Rowan Collins: 2 posts

People

Translate

site design / logo © 2019 Grokbase