# Casting a PHP type, new SAPI

- Thread: https://externals.io/message/80858
- Original archive: https://news-web.php.net/php.internals/80858
- Started by Kevin Ingwersen Ingwie Phoenix on 2015-01-20T05:36:30+00:00
- Messages: 5
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #80858 — Kevin Ingwersen Ingwie Phoenix — 2015-01-20T05:36:30+00:00

URL: https://externals.io/message/80858#80858

Good morning, everyone.

Today I have started to concept a new SAPI which I have wanted to do in quite a while now. To learn more, here is a README: https://github.com/IngwiePhoenix/php-jrp/blob/master/README.md <https://github.com/IngwiePhoenix/php-jrp/blob/master/README.md>

But in order for me to work this out as good as I can - especially the PHP API at the bottom - I need to know just a thing I could not find within the public PHP headers: When I have an Array, now can I turn that into an object?

I’d be happy to hear what you think of this concept as well. As mentioned in the README, process on this will begin later. For now, I am going to use helper libraries, but late ron I want to strip the project to lesser and lesser dependencies. But it will remain being written in C++.

Kind regards,
Ingwie

---

## #80860 — Bas van Beek — 2015-01-20T07:58:26+00:00

URL: https://externals.io/message/80858#80860 · In reply to: #80858

Hi Ingwie,

I fail to see why this would be considered a SAPI? It doesn't seem to integrate with application code written in another language to exchange data between php userland and local application variables. 

Just seems like you're trying to accomplish a dedicated server/daemon that listens for messages on a TCP port with a self developed JSON protocol and answers according to that protocol. If that is what you are trying to accomplish you could do that easily in PHP userland using CLI.

Much better approach would be using such a CLI script together with an event based messaging system waiting for incoming messages using technologies like gearman, activemq, kafka, etc. This would give you so much more power in ways of load balancing, fail-over and/or replication and multi 
language support that I see no use for JRP, as all can be done within a matter of hours using regular existing PHP extensions and the CLI executor.

Bas van Beek


> Op 20 jan. 2015, om 06:36 heeft Kevin Ingwersen (Ingwie Phoenix) <ingwie2000@googlemail.com> het volgende geschreven:
> 
> Good morning, everyone.
> 
> Today I have started to concept a new SAPI which I have wanted to do in quite a while now. To learn more, here is a README: https://github.com/IngwiePhoenix/php-jrp/blob/master/README.md <https://github.com/IngwiePhoenix/php-jrp/blob/master/README.md>
> 
> But in order for me to work this out as good as I can - especially the PHP API at the bottom - I need to know just a thing I could not find within the public PHP headers: When I have an Array, now can I turn that into an object?
> 
> I’d be happy to hear what you think of this concept as well. As mentioned in the README, process on this will begin later. For now, I am going to use helper libraries, but late ron I want to strip the project to lesser and lesser dependencies. But it will remain being written in C++.
> 
> Kind regards,
> Ingwie

---

## #80909 — johannes@schlueters.de — 2015-01-20T22:11:44+00:00

URL: https://externals.io/message/80858#80909 · In reply to: #80858

Hi,

On Tue, 2015-01-20 at 06:36 +0100, Kevin Ingwersen (Ingwie Phoenix)
wrote:
> Today I have started to concept a new SAPI which I have wanted to do
> in quite a while now. To learn more, here is a README:
> https://github.com/IngwiePhoenix/php-jrp/blob/master/README.md
> <https://github.com/IngwiePhoenix/php-jrp/blob/master/README.md>

I have to agree with Bas van Beek that I don't see the benefit of using
a custom protocol over existing ones. This protocol doesn't seem to have
less overhead than HTTP and you loose ability of using established
libraries, debugging tools, scaling tools, ... 

Anyways:

> But in order for me to work this out as good as I can - especially the
> PHP API at the bottom - I need to know just a thing I could not find
> within the public PHP headers: When I have an Array, now can I turn
> that into an object?

What does that mean? Object in PHP-sense or in C-sense or C++-sense or
JSON? They are all different things.

PHP arrays essentially are a zval with a HashTable, which can be used
via zend_hash.h API, there also exist some array_* shortcuts in
zend_API.h, this changes a bit between PHP 5 and 7 so you should pick
the version.

If you want a PHP object you use the object APIs, I tend take ideas from
the reflection's implementation as it does most object things.

If you want the equivalent of  $obj = (object)$array; I question whether
that makes sense (you want to write json output in the end, no? so why
do an relative expensive transformation instead of directly creating
json?) but convert_to_object() in zend_operators.c is your friend.

You want to create a JSON object? Look at the json extension, which
doesn't have an API but is trivial to copy. (mind the license of the
utf8 decoder, if needed)

Unless you have precise questions it's hard to answer expect pointing
out default resources (PHP source, Sara's book,
phpinternalsbook.com, ...)

> I’d be happy to hear what you think of this concept as well. As
> mentioned in the README, process on this will begin later. For now, I
> am going to use helper libraries, but late ron I want to strip the
> project to lesser and lesser dependencies. But it will remain being
> written in C++.

One thing I noticed is that you have a dependency on some thread
libraries (while I wonder why C++08 libraries instead of C++11's thread
support). Using  threads means pain with PHP. One thing is TSRM (while
replaced in PHP 7 with TLS) the other thing is stability: A crash in one
thread will crash the whole server, in a process-based model like
FastCGI or apache mod_prefork only the single process and request will
die. Crashing PHP is trivial (infinite recursion etc.)

I also see PHP-CPP in your dependencies, that is nice but for writing
extensions, not SAPIs. And last time it checked it didn't really do good
under TSRM (haven't checked for some time)

My example I use to answer SAPI questions is
https://github.com/johannes/pconn-sapi which is probably the most simple
SAPI available, working both in threaded and non-threaded mode.

johannes

---

## #81026 — Kevin Ingwersen Ingwie Phoenix — 2015-01-23T06:38:27+00:00

URL: https://externals.io/message/80858#81026 · In reply to: #80909

> Am 20.01.2015 um 23:11 schrieb Johannes Schlüter <johannes@schlueters.de>:
> 
> Hi,
> 
> On Tue, 2015-01-20 at 06:36 +0100, Kevin Ingwersen (Ingwie Phoenix)
> wrote:
> > […]
> 
> I have to agree with Bas van Beek that I don't see the benefit of using
> a custom protocol over existing ones. This protocol doesn't seem to have
> less overhead than HTTP and you loose ability of using established
> libraries, debugging tools, scaling tools, ... 
…but you gain the headache of FastCGI. I just wasted 3 hours, trying to get this working right. It was more of an issue with the script language I am using to write the web server - but getting my head around FastCGI in the first place is a mess. When was it written and published, 1996?

> Anyways:
> 
> > […]
> 
> What does that mean? Object in PHP-sense or in C-sense or C++-sense or
> JSON? They are all different things.
Oh damn. I should ahve been more clear there. I was reffering to a PHP object.

> PHP arrays essentially are a zval with a HashTable, which can be used
> via zend_hash.h API, there also exist some array_* shortcuts in
> zend_API.h, this changes a bit between PHP 5 and 7 so you should pick
> the version.
> 
> If you want a PHP object you use the object APIs, I tend take ideas from
> the reflection's implementation as it does most object things.
> 
> If you want the equivalent of  $obj = (object)$array; I question whether
> that makes sense (you want to write json output in the end, no? so why
> do an relative expensive transformation instead of directly creating
> json?) but convert_to_object() in zend_operators.c is your friend.
> 
> You want to create a JSON object? Look at the json extension, which
> doesn't have an API but is trivial to copy. (mind the license of the
> utf8 decoder, if needed)
> 
> Unless you have precise questions it's hard to answer expect pointing
> out default resources (PHP source, Sara's book,
> phpinternalsbook.com, …)
Since there is no „object syntax“ in PHP as there is in JavaScript for instance, I can’t pass an actual object and need to hack my way around and use an associative array instead. Because there is a difference in doing

$obj = new stdClasS;
$obj->propA=…;
$obj->propB=…;
func($obj);

And

func([propA=>..., propB=>...]); // my Mail program mis-fixes quotes, so I left them out

And in the end, all I need is to iterate over each key - at which I realized, I dont even need to convert it into an Object at all and can use the existing HashTable API… My failure on that.

> > […]
> 
> One thing I noticed is that you have a dependency on some thread
> libraries (while I wonder why C++08 libraries instead of C++11's thread
> support).
Mostly because the C++11 support across compilers is very wobbly. TinyThread++ has the C++11 API mirrored, so it can be replaced by the STL threads on a newer compiler. But for anything that doesnt support the C++11 threads correctly, this library can do.

> Using  threads means pain with PHP. One thing is TSRM (while
> replaced in PHP 7 with TLS)[...]
I thought TSRM was stable?

> [...]the other thing is stability: A crash in one
> thread will crash the whole server, in a process-based model like
> FastCGI or apache mod_prefork only the single process and request will
> die. Crashing PHP is trivial (infinite recursion etc.)
My idea was to use a thread per process watchdog. So a request is started, and it is given to a new thread - so it has its own PHP process running and when that one dies, it can send back an error message accordingly. PHP was not ment to run in the same process in the first place.

> I also see PHP-CPP in your dependencies, that is nice but for writing
> extensions, not SAPIs. And last time it checked it didn't really do good
> under TSRM (haven't checked for some time)
It is fine with TSRM, actually. I only want to use it to simplify the built-in extension that allows custom messages to be sent back to the client (the instance that issued the request).

> My example I use to answer SAPI questions is
> https://github.com/johannes/pconn-sapi which is probably the most simple
> SAPI available, working both in threaded and non-threaded mode.
Where else do you think I am getting all the SAPI docs I need in a cheat-sheet form? :)

To clarify: I mainly want to replace FastCGI. Its a pain to work with and I am spending more time on getting a proper FastCGI connection going than writing on my site. There is a good reason that programs like NodeJS allow webservers to be scripted; t make things very custom and dynamic. But since PHP’s only output seems to be FastCGI, the CLI - which doesn’t, obviously, support the header stuff - or probably something i have overlooked, I will need to write my own…

 `pcntl_fork()` is not in the standart PHP it seems, otherwise I would have written JRP using that. But since this is going to be a general-purpose SAPI anyway, I can just write it in C++ from the get-go.

Kind regards, Ingwie

---

## #81044 — johannes@schlueters.de — 2015-01-23T14:34:24+00:00

URL: https://externals.io/message/80858#81044 · In reply to: #81026

On Fri, 2015-01-23 at 07:38 +0100, Kevin Ingwersen (Ingwie Phoenix)
wrote:
> > […]
> …but you gain the headache of FastCGI. I just wasted 3 hours, trying
> to get this working right. It was more of an issue with the script
> language I am using to write the web server - but getting my head
> around FastCGI in the first place is a mess. When was it written and
> published, 1996?

Written and published in 1996 means there are stable tools and
libraries ;-)
And well, a few hours learning FastCGI vs. long time to invent something
new. But your call, and maybe you are successful and create something
better ... 

> > […]
> I thought TSRM was stable?

TSRM itself is stable. Doesn't mean it's good. It has a notable
performance penalty (Zend/bench.php on my machine with 5.6 is ca. 2.0s
vs 2.6s, also requires more memory, this is better in PHP 7, but not
perfect either) and is less tested (I doubt we have many devs actually
running in a threaded context to observe races, true, it's some time
since I debugged such a thing but don't know how many of our "can't
reproduce" bugs are threading issues ...)

> > […]
> My idea was to use a thread per process watchdog. So a request is
> started, and it is given to a new thread - so it has its own PHP
> process running and when that one dies, it can send back an error
> message accordingly. PHP was not ment to run in the same process in
> the first place.

If PHP crashes due to something like
        $ php -nr 'function a() { call_user_func("a"); } a();'
        Segmentation fault (core dumped)
your watchdog thread will die, too, as will each other PHP thread in the
same process. (yes, eventually one could catch `SIGSEGV` and then try to
do some magic but welcome to devil's kitchen)

> `pcntl_fork()` is not in the standart PHP it seems, otherwise I would
> have written JRP using that. But since this is going to be a
> general-purpose SAPI anyway, I can just write it in C++ from the
> get-go.

pcntl_fork is a default extension for CLI SAPI, for other SAPIs it's
disabled. Distributors sometimes split that up differently. Properly
forking however is complicated when having opened resources. Also this
sounds like long running scripts ... since 5.3's GC it's better, but
PHP's memory and resource handling isn't really aimed at scripts running
longer than a few milliseconds.

johannes
