Added PHP Extensions talk for TEK.

This commit is contained in:
Derick Rethans
2017-05-23 15:48:00 -04:00
parent ad6b64e3e7
commit 83cac790a8
59 changed files with 1821 additions and 25 deletions

57
php-ext-tek17.xml Normal file
View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<presentation css="10gen-strict.css">
<topic>MongoDB</topic>
<title>Introduction into PHP Extensions</title>
<event>php[tek]</event>
<location>Atlanta, GA, USA</location>
<date>June 25th, 2017</date>
<speaker>Derick Rethans</speaker>
<email>derick@mongodb.com</email>
<twitter>derickr</twitter>
<url>http://derickrethans.nl/talks.html</url>
<joindin>https://joind.in/21363</joindin>
<slide>slides/mongodb/title.xml</slide>
<slide>slides/mongodb/me.xml</slide>
<slide>slides/internals/extension-agenda.xml</slide>
<slide>slides/internals/extension-agenda2.xml</slide>
<slide>slides/internals/extension-what1.xml</slide>
<slide>slides/internals/extension-why1.xml</slide>
<slide>slides/internals/extension-why-wrap.xml</slide>
<slide>slides/internals/extension-why-not-possible.xml</slide>
<slide>slides/internals/extension-why-speed.xml</slide>
<slide>slides/internals/rdp-intro.xml</slide>
<slide>slides/internals/rdp-intro2.xml</slide>
<slide>slides/internals/rdp-intro3.xml</slide>
<slide>slides/internals/rdp-intro4.xml</slide>
<slide>slides/internals/extension-parts.xml</slide>
<slide>slides/internals/extension-on-a-slide.xml</slide>
<slide>slides/internals/config.m4.xml</slide>
<slide>slides/internals/config.w32.xml</slide>
<slide>slides/internals/phpize.xml</slide>
<slide>slides/internals/extension.h.xml</slide>
<slide>slides/internals/extension.c-part1.xml</slide>
<slide>slides/internals/extension.c-part2.xml</slide>
<slide>slides/internals/extension.c-part3.xml</slide>
<slide>slides/internals/function.xml</slide>
<slide>slides/internals/rdp_simplify-part1.xml</slide>
<slide>slides/internals/rdp_simplify-zedval.xml</slide>
<slide>slides/internals/rdp_simplify-part1b.xml</slide>
<slide>slides/internals/rdp_simplify-convert-data.xml</slide>
<slide>slides/internals/rdp_simplify-run-algorithm.xml</slide>
<slide>slides/internals/rdp_simplify-php.xml</slide>
<slide>slides/internals/rdp_simplify-c.xml</slide>
<slide>slides/internals/rdp_simplify-return-result.xml</slide>
<slide>slides/internals/rdp_simplify-return-scalars.xml</slide>
<slide>slides/internals/memory-management.xml</slide>
<slide>slides/internals/tests.xml</slide>
<slide>slides/internals/rdp-test.xml</slide>
<slide>slides/mongodb/questions.xml</slide>
<slide>slides/mongodb/resources.xml</slide>
</presentation>

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
slides/internals/agenda.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@@ -1,4 +1,3 @@
<slide style="title">
<slide style="title" background="abstract-tree.jpg">
<title>Abstract Syntax Tree</title>
<image align="center" filename="abstract-tree.jpg" attr=""/>
</slide>

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -1,4 +1,3 @@
<slide style="title">
<slide style="title" background="branches.jpg" background_attr="Sergey Kochkarev - https://www.flickr.com/photos/skochkar/24747666840/ - Public Domain">
<title>Branch Analysis</title>
<image align="center" filename="branches.jpg" attr="Sergey Kochkarev - https://www.flickr.com/photos/skochkar/24747666840/ - Public Domain"/>
</slide>

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

View File

@@ -1,4 +1,3 @@
<slide style="title">
<slide style="title" background="bytecode.jpg">
<title>Byte Code</title>
<image align="center" filename="bytecode.jpg" attr=""/>
</slide>

View File

@@ -1,4 +1,3 @@
<slide style="title">
<slide style="title" background="catch.jpg" background_attr="Soggydan Benenovitch (https://www.flickr.com/photos/38518750@N00/4858510277)">
<title>Exceptions (Try/Catch)</title>
<image align="center" filename="catch.jpg" attr="Soggydan Benenovitch (https://www.flickr.com/photos/38518750@N00/4858510277)"/>
</slide>

View File

@@ -0,0 +1,23 @@
<slide>
<title>Build Instructions</title>
<subtitle>config.m4</subtitle>
<blurb>Comments:</blurb>
<example><![CDATA[
dnl $Id$
dnl config.m4 for extension geospatial
]]></example>
<blurb>Configure option definition:</blurb>
<example><![CDATA[
PHP_ARG_ENABLE(geospatial, whether to enable geospatial support,
[ --enable-geospatial Enable geospatial support])
]]></example>
<blurb>Build instructions:</blurb>
<example><![CDATA[
if test "$PHP_GEOSPATIAL" != "no"; then
PHP_NEW_EXTENSION(geospatial, geospatial.c geo_array.c, $ext_shared)
fi
]]></example>
</slide>

View File

@@ -0,0 +1,23 @@
<slide>
<title>Build Instructions</title>
<subtitle>config.w32</subtitle>
<blurb>Comments:</blurb>
<example><![CDATA[
// $Id$
// vim:ft=javascript
]]></example>
<blurb>Configure option definition:</blurb>
<example><![CDATA[
ARG_ENABLE("geospatial", "enable geospatial support", "no");
]]></example>
<blurb>Build instructions:</blurb>
<example><![CDATA[
if (PHP_GEOSPATIAL != "no") {
EXTENSION("geospatial", "geospatial.c geo_array.c");
}
]]></example>
</slide>

View File

@@ -1,4 +1,3 @@
<slide style="title">
<slide style="title" background="rosetta.jpg" background_attr="Cristian Bortes - https://www.flickr.com/photos/bortescristian/2931856207 - CC-BY">
<title>Dead Code</title>
<image align="center" filename="rosetta.jpg" attr="Cristian Bortes - https://www.flickr.com/photos/bortescristian/2931856207 - CC-BY"/>
</slide>

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 254 KiB

View File

@@ -0,0 +1,3 @@
<slide style="title" background="agenda.png">
<title>Agenda</title>
</slide>

View File

@@ -0,0 +1,11 @@
<slide>
<title>Questions</title>
<list>
<bullet>What are extensions?</bullet>
<bullet>Why would you write an extension?</bullet>
<bullet>How do you write an extension?</bullet>
</list>
<break/>
<image filename="elephpants.jpg"/>
</slide>

View File

@@ -0,0 +1,13 @@
<slide>
<title>What makes up an Extension?</title>
<list>
<bullet>%config.m4%: configure options and build instructions</bullet>
<bullet>%php_extension.h%: header files and glue</bullet>
<bullet>%extension.c%: extension definition and function implementation</bullet>
</list>
<break/>
<list>
<bullet>%algorithms.c%: C implementation of algorithms</bullet>
</list>
</slide>

View File

@@ -0,0 +1,12 @@
<slide>
<title>What are extensions?</title>
<list>
<bullet>Additional functions and classes</bullet>
<bullet>Written in C</bullet>
<bullet>Either compiled in, or a shared object</bullet>
<bullet>Bundled with PHP, distributed through PECL, or distributed separately</bullet>
</list>
<break/>
<image filename="limo.png" attr="https://commons.wikimedia.org/wiki/File:Luxury_Stretched_Limousine_Cadillac.png - Keithmsyverson - CC-BY 4.0"/>
</slide>

View File

@@ -0,0 +1,9 @@
<slide background="escher.jpg">
<title>Unpossible in userland</title>
<break lines="3"/>
<list>
<bullet>Information or resources shared between requests: *persistent connections*, *PHP objects*</bullet>
<bullet>Peeking into internals: *vld*, *Xdebug*, *opcache*</bullet>
</list>
</slide>

View File

@@ -0,0 +1,9 @@
<slide background="tracing.jpg">
<title>Speed</title>
<break lines="3"/>
<list>
<bullet>PHP is fast, but things can be ~faster~</bullet>
<bullet>Implementations in C (and C++) usually ~outperform~ code in PHP</bullet>
</list>
</slide>

View File

@@ -0,0 +1,10 @@
<slide background="bubble-wrap.jpg" background_attr="https://pixabay.com/en/bubble-wrap-blow-packaging-1183728/ — CC0">
<title>Wrapping Libraries</title>
<break lines="3"/>
<list>
<bullet>Database drivers: *libmongoc*, *libmysql*, …</bullet>
<bullet>Image processing: *GD*, *Cairo*, *ImageMagick*, …</bullet>
<bullet>Image recognition: *OpenCV*, *Dlib*, …</bullet>
</list>
</slide>

View File

@@ -0,0 +1,11 @@
<slide>
<title>Why write an extension?</title>
<list>
<bullet>Wrap existing library</bullet>
<bullet>Not everything can be done in userland</bullet>
<bullet>Speed</bullet>
</list>
<break/>
<image filename="limo.png" attr="https://commons.wikimedia.org/wiki/File:Luxury_Stretched_Limousine_Cadillac.png - Keithmsyverson - CC-BY 4.0"/>
</slide>

View File

@@ -0,0 +1,30 @@
<slide>
<title>The Meat</title>
<blurb>Header inclusions:</blurb>
<example><![CDATA[
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_geospatial.h"
#include "Zend/zend_exceptions.h"
#include "ext/spl/spl_exceptions.h"
]]></example>
<blurb>Argument Information:</blurb>
<example><![CDATA[
ZEND_BEGIN_ARG_INFO_EX(rdp_simplify_args, 0, 0, 2)
ZEND_ARG_INFO(0, pointsArray)
ZEND_ARG_INFO(0, epsilon)
ZEND_END_ARG_INFO()
]]></example>
<blurb>List of functions:</blurb>
<example><![CDATA[
const zend_function_entry geospatial_functions[] = {
PHP_FE(rdp_simplify, rdp_simplify_args)
{ NULL, NULL, NULL }
};
]]></example>
</slide>

View File

@@ -0,0 +1,31 @@
<slide>
<title>The Meat</title>
<blurb>Module (Extension) definition:</blurb>
<example><![CDATA[
zend_module_entry geospatial_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"geospatial",
geospatial_functions,
PHP_MINIT(geospatial),
NULL,
NULL,
NULL,
PHP_MINFO(geospatial),
#if ZEND_MODULE_API_NO >= 20010901
PHP_GEOSPATIAL_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
};
]]></example>
<blurb>Handle Shared Object Loading:</blurb>
<example><![CDATA[
#ifdef COMPILE_DL_GEOSPATIAL
ZEND_GET_MODULE(geospatial)
#endif
]]></example>
</slide>

View File

@@ -0,0 +1,24 @@
<slide>
<title>The Meat</title>
<blurb>Module INITialisation</blurb>
<example><![CDATA[
PHP_MINIT_FUNCTION(geospatial)
{
REGISTER_DOUBLE_CONSTANT("GEO_DEG_TO_RAD", GEO_DEG_TO_RAD, CONST_CS|CONST_PERSISTENT);
return SUCCESS;
}
]]></example>
<blurb>Module INFO</blurb>
<example><![CDATA[
PHP_MINFO_FUNCTION(geospatial)
{
php_info_print_table_start();
php_info_print_table_header(2, "Geospatial functions", "enabled");
php_info_print_table_row(2, "Version", PHP_GEOSPATIAL_VERSION);
php_info_print_table_end();
}
]]></example>
</slide>

View File

@@ -0,0 +1,33 @@
<slide>
<title>Header File</title>
<blurb>Guard:</blurb>
<example><![CDATA[
#ifndef PHP_GEOSPATIAL_H
#define PHP_GEOSPATIAL_H
]]></example>
<example><![CDATA[
#define PHP_GEOSPATIAL_VERSION "0.1.1-dev"
]]></example>
<blurb>Module definition:</blurb>
<example><![CDATA[
extern zend_module_entry geospatial_module_entry;
#define phpext_geospatial_ptr &geospatial_module_entry
]]></example>
<blurb>Module initialiser declarations:</blurb>
<example><![CDATA[
PHP_MINIT_FUNCTION(geospatial);
PHP_MINFO_FUNCTION(geospatial);
]]></example>
<blurb>Forward declarations:</blurb>
<example><![CDATA[
PHP_FUNCTION(rdp_simplify);
#endif /* PHP_GEOSPATIAL_H */
]]></example>
</slide>

View File

@@ -0,0 +1,13 @@
<slide>
<title>Implementing the function</title>
<list>
<bullet>Parse Input Parameters</bullet>
<bullet>Convert Data into Right Format</bullet>
<bullet>Run Algorithm</bullet>
<bullet>Return Result</bullet>
</list>
<break lines="3"/>
<image filename="einstein.jpg"/>
</slide>

BIN
slides/internals/inputs.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -1,4 +1,3 @@
<slide style="title">
<slide style="title" background="jumps.jpg" background_attr="Thor-Wiggo Skille (http://www.nfk.no/Artikkel.aspx?AId=25071&amp;back=1&amp;MId1=4557&amp;MId2=&amp;MId3=&amp;)">
<title>Jumps</title>
<image align="center" filename="jumps.jpg" attr="Thor-Wiggo Skille (http://www.nfk.no/Artikkel.aspx?AId=25071&amp;back=1&amp;MId1=4557&amp;MId2=&amp;MId3=&amp;)"/>
</slide>

BIN
slides/internals/limit.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

BIN
slides/internals/limo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 KiB

View File

@@ -1,4 +1,3 @@
<slide style="title">
<slide style="title" background="loops.png" background_attr="http://xkcd.com/657">
<title>Complex Loops</title>
<image align="center" filename="loops.png" attr="http://xkcd.com/657"/>
</slide>

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 KiB

View File

@@ -0,0 +1,18 @@
<slide>
<title>Memory Management</title>
<list>
<bullet>If you allocate something, you need to free it</bullet>
<bullet>PHP Memory Management helpers: %emalloc%, %efree%</bullet>
<bullet>To prevent PHP from cleaning up input arguments:<break/>
<example>Z_ADDREF(zval);</example>
</bullet>
</list>
<div effect="fade-in">
<list>
<bullet>But make sure to remove the reference later:<break/>
<example><![CDATA[zval_ptr_dtor(&zval);]]></example>
</bullet>
</list>
</div>
</slide>

View File

@@ -0,0 +1,9 @@
<slide>
<title>Building the Extension</title>
<list>
<bullet>%phpize%<break/>Brings in headers and creates %configure% script</bullet>
<bullet>%./configure%<break/>Runs system checks, and creates %Makefile%</bullet>
<bullet>%make%<break/>Builds the extension</bullet>
</list>
</slide>

View File

@@ -0,0 +1,3 @@
<slide style="title" background="limit.gif" background_attr="© Copyright OpenStreetMap and contributors — ODbL">
<title>Oh, Belgium!</title>
</slide>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
<slide>
<title>RamerDouglasPeucker algorithm</title>
<list>
<bullet>Recursive algorithm for line/polygon simplification</bullet>
<bullet>Computationally intensive</bullet>
<bullet>100 runs with episilon of 0.01:<list>
<bullet>PHP function: *45.3s*</bullet>
<bullet>C implementation in extension: *0.37s*</bullet>
</list></bullet>
</list>
<break/>
<image filename="Douglas-Peucker_animated.gif" attr="https://commons.wikimedia.org/wiki/File:Douglas-Peucker_animated.gif — CC-By_SA"/>
</slide>

View File

@@ -0,0 +1,3 @@
<slide style="title" background="warp.png" background_attr="NASA/JPL-Caltech/STScI/IRAM + Modifications">
<title>From 45.3s down to 0.37s</title>
</slide>

View File

@@ -0,0 +1,29 @@
<slide>
<title>Example Test File</title>
<blurb>%tests/rdp-belgium.phpt%</blurb>
<example inline="2"><![CDATA[
*--TEST--*
Test for rdp_simplify
*--FILE--*
&lt;?php
$json = json_decode( file_get_contents( dirname( &#95;&#95;FILE&#95;&#95; ) . '/rdp-belgium.json' ) );
$points = $json[0]->geometry->coordinates[0];
$result = RDP_Simplify( $points, 0.001 );
var_dump( count( $result ) );
$result = RDP_Simplify( $points, 0.01 );
var_dump( count( $result ) );
?>
*--EXPECT--*
int(1029)
int(261)
]]></example>
<list>
<bullet>Sections: TEST, INI, FILE, EXPECT, EXPECTF</bullet>
<bullet>Simple PHP script</bullet>
</list>
</slide>

View File

@@ -0,0 +1,42 @@
<slide>
<title>RDP (C)</title>
<example><![CDATA[
void rdp_simplify(geo_array *points, double epsilon, int start, int end)
{
double firstX = points->x[start], firstY = points->y[start];
double lastX = points->x[end], lastY = points->y[end];
int index = -1, i;
double dist = 0.0, current_dist;
if (end - start < 2) {
return;
}
for (i = start + 1; i < end; i++) {
if (!points->status[i]) {
continue;
}
current_dist = rdp_find_perpendicular_distable(points->x[i], points->y[i], firstX, firstY, lastX, lastY);
if (current_dist > dist) {
dist = current_dist;
index = i;
}
}
if (dist > epsilon) {
rdp_simplify(points, epsilon, start, index);
rdp_simplify(points, epsilon, index, end);
return;
} else {
for (i = start + 1; i < end; i++) {
points->status[i] = 0;
}
return;
}
}
]]></example>
</slide>

View File

@@ -0,0 +1,46 @@
<slide>
<title>Converting from PHP variables</title>
<div effect="fade-out">
<example><![CDATA[
points = geo_hashtable_to_array(points_array TSRMLS_CC);
if (!points) {
return;
}
]]></example>
</div>
<div effect="fade-in">
<example inline="2"><![CDATA[
geo_array \*geo_hashtable_to_array(zval \*array TSRMLS_DC)
{
geo_array *tmp;
int element_count, i = 0;
zval *entry;
double lon, lat;
element_count = *zend_hash_num_elements*(Z_ARRVAL_P(array));
*tmp = geo_array_ctor(element_count);*
*ZEND_HASH_FOREACH_VAL*(Z_ARRVAL_P(array), entry) {
if (!parse_point_pair(entry, &lon, &lat TSRMLS_CC)) {
goto failure;
}
tmp->x[i] = lon;
tmp->y[i] = lat;
tmp->status[i] = 1;
i++;
} ZEND_HASH_FOREACH_END();
return tmp;
failure:
*geo_array_dtor(tmp);*
return NULL;
}
]]></example>
</div>
</slide>

View File

@@ -0,0 +1,28 @@
<slide>
<title>Parsing Input Parameters</title>
<example inline="2"><![CDATA[
PHP_FUNCTION(rdp_simplify)
{
*zval* *points_array;
*double* epsilon;
if (*zend_parse_parameters*(ZEND_NUM_ARGS() TSRMLS_CC, *"zd"*, &points_array, &epsilon)
== FAILURE) {
return;
}
if (Z_TYPE_P(points_array) != IS_ARRAY) {
return;
}
]]></example>
<break/>
<blurb>%zend_parse_parameters%</blurb>
<list>
<bullet>A format letter for every type</bullet>
<bullet>Matched with a C data type</bullet>
<bullet>Cleaned up for you</bullet>
</list>
</slide>

View File

@@ -0,0 +1,19 @@
<slide>
<title>Parsing Input Parameters</title>
<table>
<tr><th>letter</th><th>variable</th><th>C data-type</th></tr>
<tr><td>a</td><td>array</td><td>%zval*%</td></tr>
<tr><td>b</td><td>boolean</td><td>%zend_bool%</td></tr>
<tr><td>d</td><td>double</td><td>%double%</td></tr>
<tr><td>l</td><td>long</td><td>%zend_long%</td></tr>
<tr><td>O</td><td>object of specific type</td><td>%zval*%, %zend_class_entry%</td></tr>
<tr><td>P</td><td>path</td><td>%zend_string*%</td></tr>
<tr><td>s</td><td>string</td><td>%char*%, %size_t%</td></tr>
<tr><td>S</td><td>string</td><td>%zend_string*%</td></tr>
<tr><td>z</td><td>the actual zval</td><td>%zval*%</td></tr>
</table>
<image filename="inputs.jpg" attr="Clive Darra - https://www.flickr.com/photos/fsse-info/3414368958/ - CC-BY-SA"/>
</slide>

View File

@@ -0,0 +1,42 @@
<slide>
<title>RDP (PHP)</title>
<example><![CDATA[
static private function simplifyInternal( &$points, $epsilon, $start, $end )
{
$firstPoint = $points[$start];
$lastPoint = $points[$end];
$index = -1;
$dist = 0;
if ( $end - $start < 2 ) {
return;
}
for ( $i = $start + 1; $i < $end; $i++ ) {
if ( !isset( $points[$i] ) ) {
continue;
}
$cDist = self::findPerpendicularDistance( $points[ $i ], $firstPoint, $lastPoint );
if ( $cDist > $dist ) {
$dist = $cDist;
$index = $i;
}
}
if ( $dist > $epsilon ) {
self::simplifyInternal( $points, $epsilon, $start, $index );
self::simplifyInternal( $points, $epsilon, $index, $end );
return;
} else {
for ( $i = $start + 1; $i < $end; $i++ ) {
unset( $points[$i] );
}
return;
}
}
]]></example>
</slide>

View File

@@ -0,0 +1,24 @@
<slide>
<title>Return Result</title>
<example inline="2"><![CDATA[
PHP_FUNCTION(rdp_simplify)
{
zval pair;
array_init(*return_value*);
for (i = 0; i < points->count; i++) {
if (points->status[i]) {
*array_init(&pair);*
*add_next_index_double*(&pair, points->x[i]);
add_next_index_double(&pair, points->y[i]);
*add_next_index_zval*(*return_value*, &pair);
}
}
*geo_array_dtor(points);*
}
]]></example>
</slide>

View File

@@ -0,0 +1,19 @@
<slide>
<title>Returning Scalar Values</title>
<blurb>Return Immediately:</blurb>
<example>RETURN_BOOL(!mongoc_cursor_is_alive(intern->cursor));</example>
<example>RETURN_LONG(zend_memory_usage(0));</example>
<example>RETURN_STRING(i->function.function);</example>
<break/>
<blurb>Just Set Return Value:</blurb>
<example>RETVAL_FALSE;</example>
<example>#if PHP_VERSION_ID >= 70000
RETVAL_STRING(trace_fname);
#else
RETVAL_STRING(trace_fname, 1);
#endif
</example>
</slide>

View File

@@ -0,0 +1,7 @@
<slide>
<title>Run Algorithm</title>
<example><![CDATA[ rdp_simplify(points, epsilon, 0, points->count - 1);]]></example>
<break lines="6"/>
<image filename="Douglas-Peucker_animated.gif" attr="https://commons.wikimedia.org/wiki/File:Douglas-Peucker_animated.gif — CC-By_SA"/>
</slide>

View File

@@ -0,0 +1,21 @@
<slide>
<title>zval?</title>
<blurb>PHP's representation of a value</blurb>
<list>
<bullet>Contains the type: %Z_TYPE_P(points_array)%</bullet>
<bullet>Contains the value: %Z_ARRVAL_P(points_array)%</bullet>
</list>
<break/>
<blurb>%IS_DOUBLE%, %IS_STRING%, %IS_ARRAY%, …</blurb>
<blurb>%Z_DVAL_P(lat)%, %Z_STRVAL_P(type)%, …</blurb>
<break/>
<example><![CDATA[
if (Z_TYPE_P(points_array) != IS_ARRAY) {
return;
}
]]></example>
</slide>

View File

@@ -1,4 +1,3 @@
<slide style="title">
<slide style="title" background="recap.jpg" background_attr="Jens Johnsson - https://www.pexels.com/photo/mountains-nature-arrow-guide-66100/ - CC0">
<title>Recap</title>
<image align="center" filename="recap.jpg" attr="Jens Johnsson - https://www.pexels.com/photo/mountains-nature-arrow-guide-66100/ - CC0"/>
</slide>

View File

@@ -1,4 +1,3 @@
<slide style="title">
<slide style="title" background="ring.png" background_attr="© OpenStreetMap contributors">
<title>Rings</title>
<image align="center" filename="ring.png" attr="© OpenStreetMap contributors"/>
</slide>

View File

@@ -0,0 +1,9 @@
<slide>
<title>Tests</title>
<list>
<bullet>Go into the %tests/% directory</bullet>
<bullet>%phpt% format</bullet>
<bullet>Run with %make test% in top source directory</bullet>
</list>
</slide>

View File

@@ -1,4 +1,3 @@
<slide style="title">
<slide style="title" background="tokens.jpg" background_attr="$1LENCE D00600D at English Wikipedia">
<title>Parsing</title>
<image align="center" filename="tokens.jpg" attr="$1LENCE D00600D at English Wikipedia"/>
</slide>

View File

@@ -1,4 +1,3 @@
<slide style="title">
<slide style="title" background="stages.jpg">
<title>Stages</title>
<image align="center" filename="stages.jpg" attr=""/>
</slide>

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 KiB

BIN
slides/internals/warp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@@ -1,4 +1,3 @@
<slide style="title">
<slide style="title" background="queries.jpg" background_attr="Véronique Debord-Lazaro — https://www.flickr.com/photos/debord/4932655275">
<title>Any Queries?</title>
<image align="center" filename="queries.jpg" attr="Véronique Debord-Lazaro — https://www.flickr.com/photos/debord/4932655275"/>
</slide>

View File

@@ -122,8 +122,10 @@ $('*').keypress(function(event) {
</head>
{var $img = get_attribute( $node, 'background' )}
{var $imgAttr = get_attribute( $node, 'background_attr' )}
{var $maincolor = get_attribute( $node, 'template' )}
<body{if $img} style='background-image: url({$pres->base}{$img});'{/if}>
<body{if $img} style='background-image: url({$pres->base}{$img}); background-size: cover;'{/if}>
<div class='twitter'>@derickr</div>
<div class='whole-slide{if $maincolor} template-{$maincolor}{/if}'>
{switch ( get_attribute( $node, 'type' ) )}
{case 'agenda'}
@@ -143,5 +145,6 @@ $('*').keypress(function(event) {
{/default}
{/switch}
</div>
{if $imgAttr}<p class="bgattribution">{$imgAttr}</p>{/if}
</body>
</html>