PHP, Under The Hood - DPC

Post on 18-May-2015

19.369 views 3 download

Tags:

description

PHP is one of the most popular open source programming languages in the world. It powers some of the highest traffic sites in the world, and at the same time it powers some of the lowest traffic sites in the world. But have you ever wondered how it works under the hood? Have you been overwelmed by the thought of looking at the C code that runs PHP? Well, this talk is for you! We're going to explore how PHP works under the hood, by looking at a PHP implementation of it: PHPPHP! Have you ever wondered what an OPCODE Cache is really doing? Have you ever wondered what a T_PAAMAYIM_NEKUDOTAYIM is? Have you ever wondered why an interpreted languages has a compiler? We'll explore all of these topics, and more! And the best part of it all? You don't need to know C to understand the details! Using PHPPHP, we can explore the language details in a high level language, where things like memory management don't get in the way of the real content. If you've ever wanted to know how PHP works, this is the talk for you!

Transcript of PHP, Under The Hood - DPC

PHPUnder The Hood

What Is PHP?● An Easy To Learn Language?

○ Sure!● A Simple Language?

○ Usually● A Well Designed Language?

○ HA!● An Effective Language!

○ Absolutely!

PHP Is...

Dynamically Typed

$a = 1;$b = "a";

PHP Is...

Weak Typed

1 + "1b" == 2

PHP Is...

Implementation Defined

ImplementationsMain:

C-PHP: www.php.netAlt:

HipHop - FacebookRoadsend - CompilerPhalanger - .NETPHP Compiler - CompilerPHPPHP - PHP

Interesting Note:C-PHP Requires PHP To Compile!

PHP Is...

Compiled

PHP Is...

DynamicallyCompiled

On-Demand

It All Starts With TheSAPI

SAPI● Server API● "Starts" PHP and issues request(s)● Common SAPIs:

○ CLI○ CGI (and FastCGI)○ mod_php○ FPM○ etc...

Execution Pipeline

Execution PipelineStart Up

Request

Shut Down

SAPI

Execution PipelineStart Up

Request

Shut Down

SAPIConfig Init

Engine Init

Module Init

Zend/zend.c

PHPPHP/PHP.php

Execution PipelineStart Up

Request

Shut Down

SAPI

Module Shutdown

EngineShutdown

Zend/zend.c

Execution PipelineStart Up

Request

Shut Down

SAPI

Request Init

Compile Code

Execute Code

Request Shutdown

Compiler PipelineLexer

Lexer Step● C-PHP

○ Tokenizes using RE2C○ Produces Array of Tokens

● PHPPHP○ Uses core tokenizer (or emulative)○ PHPParser Powered

Zend/zend_language_scanner.l

PHPParser/Lexer/Emulative.php

Compiler PipelineLexer

Parser

Parse Step● C-PHP

○ Directly Generates OPCode Array○ BISON Powered

● PHPPHP○ Generates AST Structure○ PHPParser Powered

Zend/zend_language_parser.y

Compiler PipelineLexer

Parser

Compiler

Compile Step● C-PHP

○ Compiled Directly During Parse○ Single Pass Compilation

● PHPPHP○ Recurses Over AST○ Single Pass (for now)○

PHPPHP/Engine/Compiler.php

Compiler PipelineLexer

Parser

Compiler

OpCode

OpCodes● A Series of Operations

○ Just like Assembler Opcodes○ Represent "units of functionality"

● Designed to run on Virtual Machine○ Zend Engine○ Or PHPPHP!

$a = 1;$b = 2;echo $a + $b;

Notice Anything?

What If We Cached The OpCodes?

We Can Cache!● Given the compiler is Idempodent

○ (has no side-effects)○ (hint: it's not)

● OpCodes are really Pointers○ Swizzling!!!

In Other Words

OpCode CachingIs Hard!

Time To Execute!

Zend/zend_vm_execute.h

PHPPHP/Engine/Executor.php

Executor Pipeline

OpCode

Is Return?No Yes

Return

But What Are We Executing?

Zend/zend_vm_execute.h

Interesting Note:vm_execute.h

Is Generated By PHP

PHPPHP/Engine/OpLines/Add.php

Variables!

Zend/zend.h

PHPPHP/Engine/Zval/Value.php

Ref-Counting● RefCount + References

○ Allows Copy-On-Write● Variable Is "Deleted" When

RefCount = 0

● Enables Primitive Garbage Collection○ Circular GC is also implemented

That's All There Is To It!

Let's Look At An Example

$a = 1;$b = 2;var_dump( $a + $b);

line # op return operands----------------------------------- 2 0 ASSIGN !0, 1 3 1 ASSIGN !1, 2 6 2 ADD ~2 !0, !1 3 SEND_VAL ~2 4 DO_FCALL 'var_dump' 5 RETURN 1

[0] => PHPPHP\Engine\OpLines\Assign[1] => PHPPHP\Engine\OpLines\Assign[2] => PHPPHP\Engine\OpLines\Add[3] => PHPPHP\Engine\OpLines\InitFCallByName[4] => PHPPHP\Engine\OpLines\Send[5] => PHPPHP\Engine\OpLines\FunctionCall[6] => PHPPHP\Engine\OpLines\ReturnOp

[0] => PHPPHP\Engine\OpLines\Assign Object (

[op1] => PHPPHP\Engine\Zval\Ptr Object (

[zval:protected] => PHPPHP\Engine\Zval\Variable Object (

[name:protected] => PHPPHP\Engine\Zval\Ptr Object (

[zval:protected] => PHPPHP\Engine\Zval\Value Object (

[value:protected] => a

[refcount:protected] => 1

[isRef:protected] =>

[dtorFunc:protected] =>

)

)

[class:protected] =>

[zval:protected] =>

[executor:protected] =>

[scope] => 1

)

)

[op2] => PHPPHP\Engine\Zval\Ptr Object (

[zval:protected] => PHPPHP\Engine\Zval\Value Object (

[value:protected] => 1

[refcount:protected] => 1

[isRef:protected] =>

[dtorFunc:protected] =>

)

)

[result] =>

[lineno] => 2

)

PHPPHP/Engine/OpLines/Assign.php

PHPPHP/Engine/OpLines/Add.php

PHPPHP/Engine/OpLines/InitFCallByName.php

PHPPHP/Engine/OpLines/Send.php

PHPPHP/Engine/OpLines/FunctionCall.php

There's A Ton More

Get Involved!

More Info● github.com/php/php-src● lxr.php.net● github.com/ircmaxell/PHPPHP

● Reference Series○ wiki.php.net○ blog.ircmaxell.com

■ PHP Internals Series

Anthony FerraraJoind.in/8443

@ircmaxellblog.ircmaxell.comircmaxell@php.netyoutube.com/ircmaxell