DEV Community

Anders Björkland
Anders Björkland

Posted on • Updated on

Do they know it's C in PHP 🎄

Just the Gist

PHP uses the C programming language to become what it is.

Correction: Earlier version of this article stated that the Zend Engine took PHP and interpreted it to C. This is not the case. The PHP source is compiled from C, the Zend engine compiles PHP into Opcodes that can be executed by the Zend VM.

It's C in a nice wrapper 🎁

While we write PHP, our basic features are provided to us from compiled C code. When we write pi(), where did that come from? Before it was compiled for us, its origin is from the C programming language:

PHP_FUNCTION(pi)
{
    ZEND_PARSE_PARAMETERS_NONE();

    RETURN_DOUBLE(M_PI);
}
Enter fullscreen mode Exit fullscreen mode

M_PI is a constant defined in the php_math.h header file:

#ifndef M_PI
#define M_PI           3.14159265358979323846  /* pi */
#endif
Enter fullscreen mode Exit fullscreen mode

And guess what? We can also call the constant M_PI from PHP and get the same result. This is really not a surprise, as we can see that the function just returns that constant.

Interpretation skills

So what is the journey for <?php echo pi() ?> to an output of 3.1415926535898? The source of PHP was compiled into a package we know as PHP, where pi() and M_PI are included. This is compiled at runtime into Opcodes by the Zend Engine. Opcodes are interpreted and executed by the engine. It's a bit like a compiler and a runtime environment rolled up into one:

  1. It analyzes the code.
  2. Then it compile it into Opcodes.
  3. And finally it executes the compiled code.

☝️ The Zend Engine is a C extension that is part of PHP. You don't have to go chasing after it on the Web if you've already got PHP for your machine. You will have all you need to run your scripts!

What about you?

What are your thoughts on the C programming language? Would you be willing to try it out, maybe even becoming a core contributor? Leave a comment below! ✍

Further Reading

Discussion (9)

Collapse
guillep2k profile image
Guillermo Prandi

Nope, not C. Saying that is akin to saying that Java is C, .Net is C, etc. You're confusing a lot of concepts here. PHP code is never transpiled ("translated") into C, nor you need a C compiler to run it afterwards (and of course, the Zend Engine doesn't have a C compiler inside). PHP is not even translated into native binary: the Zend Engine is an execution machine that uses opcodes, similar to the other aforementioned languages.

Collapse
andersbjorkland profile image
Anders Björkland Author • Edited on

Thank you for this correction, yes you're right! Would have looked like a total fool if I wrote that on the Internet 😉

Opcodes are an essential step in all of this. So double checking here: Zend compiles PHP into Opcodes and these are executed by the Zend VM. Compilation is done at run-time (if we are without cache).

Collapse
out0 profile image
out0

I don't know the specifics of PHP and I personally don't care much, but it is just a matter of theory of computation anyways.

Could a language be translated into C to be compiled ? Sure. I don't know if it's the case for PHP, but it could.

Even in thay case, it doesn't mean that you're writing in C. It means that the compiler is not getting from the language all the way down to the opcodes. Instead, the compiler strategy is to translate to another language, C in this hypothetical case, and then call another compiler to take it from there to the final binary.

It is only a compiler strategy scheme, not a sort of set of "macros" trying to modify/prettify the C language into another one.

In fact. If later on someone decides to create another compiler, that doesn't use C as basis for translation, the source language will be exactly the same.

What's important to notice here is that the language doesn't matter. It's just an organizated way of talking to the compiler.

People tend to get less and less bound to languages when they realize that all of them are the same thing.

Structured programming, functional programming, object orientation... All of the same. They're all just different ways of talking to the compiler. Nothing fancy, nothing magical. Just the cold reality :)

Thread Thread
andersbjorkland profile image
Anders Björkland Author

Nothing is special, but incredibly fascinating!

I have not gone beyond the high level languages yet, but I remember a time when I thought Java's "write once, run anywhere" were unique among these languages. I've come to see it differently of late. Seeing a similar strategy as Java's being used in language like PHP (which I thought to be very different) just drives that point further. But then we have all this about JIT compiler and it's fast going beyond what I'm prepared to learn 😅 My surface level understanding of JIT compilers is like comparing them to how generators work - as in contrast to arrays. (arrays take up memory space equal to all its elements, while generators just have the potential for all the elements and return each as they're needed).

Thread Thread
out0 profile image
out0

You should study data structure to get a better grasp of those kind of elements.

What languages provide in the standard lib (standard commands that they provide by default) are implementations of classical data structure algorithms.

Most of the modern languages end up implementing arrays using linked lists.

An array, in the traditional sense of the word, is a memory starting position and a length. So the index of the array is how much you increment the memory start position to get the next element.

So every array has to have a fixed length.

But languages can (and they do) encapsulate algorithms to make array expansion automatic, or they could even use linked lists, where each element of the array is comprised of at least 2 memory addresses: 1 for the data and 1 for the next element (or null)

So when you want to add something, you just come from the first element, then to the next, then to the next one... Until you reach the last one, than you can increment it by connecting it to the tail of that chain.

Variations of that algorithm use a little bit more memory in order to speed up add process...

To make the long story short, most of those data types they provide you will understand once you learn data structure.

Thread Thread
andersbjorkland profile image
Anders Björkland Author

Yes, I get that about arrays. I was rather thinking about arrays vs generators, as compared to compilation ahead of time vs just-in-time compilation. I don't know what languages you are used to but I believe that generators are not unique to PHP. I did a benchmark on a simple generator vs array the other day where a million-element long array with its printing took about 35.7MB of memory and the generator took 544 bytes. Quite the difference!!

Collapse
out0 profile image
out0

Opcodes are the commands of a processor. When you compile your code to the machine, it is translated into opcodes for that machine. When you compile for a VM, it's translated into opcodes for that VM.

So when we say that something is compiled to opcodes for a VM, we are saying that a virtual non existent machine will interpret this opcodes much like it (the machine) was a real computer, only that instead of running them like a real machine, it will translate those opcodes to the real machine opcodes that it is running.

The main "advantage" of that is that the code is really ubiquitous, because the machine (the virtual) is fixed.

You must have a virtual machine to every single type of hardware you intend to run your compiled code, to do the bridging. BUT, for the point of view of the developer, it looks like the code runs magically anywhere

Collapse
mindplay profile image
Rasmus Schultz

PHP is not even translated into native binary: the Zend Engine is an execution machine that uses opcodes

PHP 8 introduced just-in-time (JIT) compilation - it actually does compile opcodes to native machine instructions, like Java or C#.

Collapse
guillep2k profile image
Guillermo Prandi

OK, that's news for me. Anyway, it's definitely not C language.