$30 off During Our Annual Pro Sale. View Details »

Getting started with PHP core development - Dutch PHP Conference 2018

Getting started with PHP core development - Dutch PHP Conference 2018

Joind.in: https://joind.in/talk/4783a

While PHP’s open source community is thriving, only a relatively small number of PHP developers contribute to the number one tool they use on a daily basis: PHP itself. Although it may seem daunting to help out on a project written in C, requiring compilation and linking, getting started is actually pretty easy. In this talk I would like to share my own recent experiences of beginning to contribute to PHP itself. We will see different ways to contribute and cover some practical tips, workflows and resources, so you can start giving back to your programming language straight away!

Arnout Boks

June 08, 2018
Tweet

More Decks by Arnout Boks

Other Decks in Programming

Transcript

  1. Getting started with PHP core development
    @arnoutboks
    Arnout Boks
    #dpc18
    08-06-2018

    View Slide

  2. @arnoutboks #dpc18
    PHP Open Source projects

    View Slide

  3. @arnoutboks #dpc18
    PHP Open Source projects
    4175 contributors
    418 contributors
    689 contributors
    1497 contributors

    View Slide

  4. @arnoutboks #dpc18
    PHP Open Source projects
    4175 contributors
    418 contributors
    689 contributors
    1497 contributors

    View Slide

  5. @arnoutboks #dpc18
    PHP Open Source projects
    4175 contributors
    418 contributors
    689 contributors
    1497 contributors
    497 contributors?

    View Slide

  6. @arnoutboks #dpc18
    We all use PHP intensively
    Why not contribute something back?

    View Slide

  7. @arnoutboks #dpc18
    The catch

    View Slide

  8. @arnoutboks #dpc18
    The catch

    View Slide

  9. @arnoutboks #dpc18
    The core

    View Slide

  10. @arnoutboks #dpc18
    The core

    View Slide

  11. @arnoutboks #dpc18
    My own journey
    to the core

    View Slide

  12. @arnoutboks #dpc18
    Once upon a time…




    $doc = /* … (DOMDocument) */;
    $doc->getElementsByTagName(
    "bar"
    )->length;

    View Slide

  13. @arnoutboks #dpc18
    Once upon a time…




    $doc = /* … (DOMDocument) */;
    $doc->getElementsByTagName(
    "bar"
    )->length; // returns 2

    View Slide

  14. @arnoutboks #dpc18
    Once upon a time…




    $doc = /* … (DOMDocument) */;
    $doc->getElementsByTagNameNS(
    "http://www.example.com", "bar"
    )->length;

    View Slide

  15. @arnoutboks #dpc18
    Once upon a time…




    $doc = /* … (DOMDocument) */;
    $doc->getElementsByTagNameNS(
    "http://www.example.com", "bar"
    )->length; // returns 1

    View Slide

  16. @arnoutboks #dpc18
    Once upon a time…




    $doc = /* … (DOMDocument) */;
    $doc->getElementsByTagNameNS(
    "", "bar"
    )->length;

    View Slide

  17. @arnoutboks #dpc18
    Once upon a time…




    $doc = /* … (DOMDocument) */;
    $doc->getElementsByTagNameNS(
    "", "bar"
    )->length; // returns 0!

    View Slide

  18. @arnoutboks #dpc18
    Once upon a time…

    View Slide

  19. Reporting bugs
    Gotta squash them all

    View Slide

  20. @arnoutboks #dpc18
    bugs.php.net
    PHP bug tracker

    View Slide

  21. @arnoutboks #dpc18
    Write good bug reports
    https://bugs.php.net/how-to-report.php

    View Slide

  22. @arnoutboks #dpc18
    Search for existing bugs

    View Slide

  23. @arnoutboks #dpc18
    Sharpen bug details
    Report different platform/version:
    Don’t post “me too” comments –
    Do post other relevant details

    View Slide

  24. @arnoutboks #dpc18
    Help triaging bugs!
    https://bugs.php.net/random

    View Slide

  25. Building PHP from git
    Living on the edge

    View Slide

  26. @arnoutboks #dpc18
    1. Install dependencies
    • git
    • build-essential
    • autoconf
    • automake
    • libtool
    • re2c
    • bison
    • libxml2-dev
    Using apt-get, yum or similar

    View Slide

  27. @arnoutboks #dpc18
    2. Clone php-src
    $ git clone https://github.com/php/php-
    src.git

    View Slide

  28. @arnoutboks #dpc18
    3. Generate ./configure script
    $ ./buildconf
    Uses autoconf to build ./configure from:
    • configure.ac
    • acinclude.m4
    • sapi/*/config.m4
    • ext/*/config.m4

    View Slide

  29. @arnoutboks #dpc18
    4. Run ./configure script
    $ ./configure
    Configure a default PHP build:
    $ ./configure --disable-cgi --disable-dom
    --enable-opcache --with-sqlite3=/path
    /to/sqlite3
    Customize extensions/SAPIs:
    $ ./configure --help
    See all options

    View Slide

  30. @arnoutboks #dpc18
    5. Compile
    $ make
    $ make –j`nproc`
    To use all available cores (faster):

    View Slide

  31. @arnoutboks #dpc18
    6. Run!
    $ sapi/cli/php --version
    Binaries are in sapi/cli/php and sapi/cgi/php-cgi:

    View Slide

  32. @arnoutboks #dpc18
    Subsequent builds
    $ make
    Just run
    Recompiles only files that have changed

    View Slide

  33. @arnoutboks #dpc18
    Cleanup scripts
    $ make clean
    # try again
    $ make distclean
    # try again
    $ ./buildconf –force
    $ ./configure
    # try again
    If compilation fails, try (subsequently):
    Might be needed after git pull/git checkout

    View Slide

  34. @arnoutboks #dpc18
    https://wiki.php.net/
    internals/windows/stepbystepbuild
    Building for Windows

    View Slide

  35. @arnoutboks #dpc18

    View Slide

  36. @arnoutboks #dpc18
    • ramsey/vagrant-php-src-
    dev
    • rlerdorf/php7dev
    Vagrant boxes for compiling PHP

    View Slide

  37. @arnoutboks #dpc18
    Or use Docker:
    aboks/php-src-devtools

    View Slide

  38. @arnoutboks #dpc18
    Using php-src-devtools
    $ composer global require aboks/php-src-
    devtools
    $ git clone https://github.com/php/php-
    src.git && cd php-src
    $ php-src-devtools build

    View Slide

  39. Running tests for PHP
    Human-driven CI

    View Slide

  40. @arnoutboks #dpc18
    Running tests
    $ sapi/cli/php run-tests.php –p
    `pwd`/sapi/cli/php

    View Slide

  41. @arnoutboks #dpc18
    Running tests
    $ sapi/cli/php run-tests.php –p
    `pwd`/sapi/cli/php
    $ sapi/cli/php run-tests.php -P

    View Slide

  42. @arnoutboks #dpc18
    Running tests
    $ sapi/cli/php run-tests.php –p
    `pwd`/sapi/cli/php
    $ sapi/cli/php run-tests.php -P
    $ make test
    # (or, with php-src-devtools)
    $ php-src-devtools test

    View Slide

  43. @arnoutboks #dpc18
    Running tests
    $ make test
    […]
    PASS Trivial "Hello World" test [tests/basic/001.phpt]
    SKIP Check libcurl config on windows
    [ext/curl/tests/check_win_config.phpt] reason: for
    windows only
    FAIL Compiled regex cache limit [ext/pcre/tests/cache_limit.phpt]
    XFAIL Inconsistencies when accessing protected members
    [Zend/tests/access_modifiers_008.phpt]
    XFAIL REASON: Discussion: http://marc.info/?l=php-
    internals&m=120221184420957&w=2
    […10000 more lines of output…]

    View Slide

  44. @arnoutboks #dpc18
    Running tests
    $ make test
    […]
    =========================================
    TEST RESULT SUMMARY
    -----------------------------------------
    Number of tests : 14896 12520
    Tests skipped : 2376 ( 16.0%) --------
    Tests warned : 2 ( 0.0%) ( 0.0%)
    Tests failed : 175 ( 1.2%) ( 1.4%)
    Expected fail : 44 ( 0.3%) ( 0.4%)
    Tests passed : 12299 ( 82.6%) ( 98.2%)
    -----------------------------------------
    Time taken : 2937 seconds

    View Slide

  45. @arnoutboks #dpc18
    Running tests
    $ make test
    […]
    You may have found a problem in PHP.
    This report can be automatically sent to the PHP QA team at
    http://qa.php.net/reports and
    http://news.php.net/php.qa.reports
    This gives us a better understanding of PHP's behavior.
    If you don't want to send the report immediately you can
    choose
    option "s" to save it. You can then email it to qa-
    [email protected] later.
    Do you want to send this report now? [Yns]:|

    View Slide

  46. @arnoutboks #dpc18
    Options for running tests
    $ make test TESTS=path/to/my/test.phpt
    $ make test TESTS=ext/dom
    $ make test TESTS="--verbose ext/dom"
    $ make test TESTS=--help

    View Slide

  47. Writing tests for PHP
    “the best bug report”

    View Slide

  48. @arnoutboks #dpc18
    Steps to reproduce for bug #67474
    Test script:
    ---------------
    $doc = new DOMDocument();
    $doc->loadXML('');
    $list = $doc->getElementsByTagNameNS('', 'a');
    echo $list->length;
    Expected result:
    ----------------
    1
    Actual result:
    --------------
    0

    View Slide

  49. @arnoutboks #dpc18
    Testing tools
    Typical PHP project:
    • Written in PHP
    • Tests written in PHP
    (PHPUnit, PHPSpec, CodeCeption)
    The PHP core:
    • Written in C
    • Tests written in …

    View Slide

  50. @arnoutboks #dpc18
    PHP is tested using
    PHPT tests
    No C skills required

    View Slide

  51. @arnoutboks #dpc18
    PHPT tests
    • Basically plaintext with sections
    • Some sections (can) contain PHP code
    • Let PHP print some output…
    • …and check against expected output

    View Slide

  52. @arnoutboks #dpc18
    Very simple PHPT test
    --TEST--
    Basic arithmetic - addition
    --FILE--
    var_dump(42 + 1);
    ?>
    --EXPECT--
    int(43)

    View Slide

  53. @arnoutboks #dpc18
    Very simple PHPT test
    --TEST--
    Basic arithmetic - addition
    --FILE--
    var_dump(42 + 1);
    ?>
    --EXPECT--
    int(43)

    View Slide

  54. @arnoutboks #dpc18
    PHPT test for bug #67474
    --TEST--
    Bug #67474 getElementsByTagNameNS and default namespace
    --FILE--
    $doc = new DOMDocument();
    $doc->loadXML('');
    $list = $doc->getElementsByTagNameNS('', 'a');
    var_dump($list->length);
    ?>
    --EXPECT--
    int(1)

    View Slide

  55. @arnoutboks #dpc18
    Running our PHPT test
    $ make test TESTS=ext/dom/tests/bug67474.phpt
    […]
    =============================================
    FAILED TEST SUMMARY
    ---------------------------------------------
    Bug #67474 getElementsByTagNameNS and default
    namespace [ext/dom/tests/bug67474.phpt]
    =============================================

    View Slide

  56. @arnoutboks #dpc18
    Running our PHPT test
    Files generated for our failing test:
    bug67474.php contents of the FILE section
    bug67474.sh shell script for running the .php file
    bug67474.exp expected output
    bug67474.out actual output
    bug67474.diff diff between expected and actual
    bug67474.log log file, including the expected and
    actual output

    View Slide

  57. @arnoutboks #dpc18
    Running our PHPT test
    $ cat ext/dom/tests/bug67474.log
    ---- EXPECTED OUTPUT
    int(1)
    ---- ACTUAL OUTPUT
    int(0)
    ---- FAILED

    View Slide

  58. @arnoutboks #dpc18
    Running our PHPT test

    View Slide

  59. @arnoutboks #dpc18
    Sections in PHPT files
    GET, POST, PUT, COOKIE, HEADERS: Simulate HTTP input
    to the PHP script in FILE
    --GET--
    foo=bar&baz=qux
    --COOKIE--
    foo=bar;baz=qux
    --FILE--

    --EXPECT--
    string(6) "barbar"

    View Slide

  60. @arnoutboks #dpc18
    Sections in PHPT files
    EXPECTF, EXPECTREGEX: Expect the output to match a
    certain format
    --FILE--
    $fp = fopen(__FILE__, 'r');
    var_dump($fp);
    ?>
    --EXPECTF--
    resource(%d) of type (stream)

    View Slide

  61. @arnoutboks #dpc18
    More sections in PHPT files
    SKIPIF: Skips the test if the code in SKIPIF generates
    output containing ‘skip’ somewhere
    CLEAN: Cleans up after the test
    INI: Specifies custom php.ini directives for the test
    XFAIL: Indicates the test is expected to fail, and gives an
    explanation why

    View Slide

  62. @arnoutboks #dpc18
    Easy way to get started
    without C skills

    View Slide

  63. @arnoutboks #dpc18
    Finding untested code
    gcov.php.net

    View Slide

  64. @arnoutboks #dpc18
    Resources
    • https://qa.php.net/write-test.php
    • https://www.sammyk.me/compiling-php-from-source-
    writing-tests-for-php-source
    • https://phptestfest.org/tutorials/
    • http://www.phpinternalsbook.com/#testing-php-
    source
    • https://github.com/PHPTestFestBrasil/phptt
    • https://gist.github.com/SammyK/4a5cf70d0973731d0c
    85b151a323ea2d

    View Slide

  65. Editing the PHP source
    Your own custom PHP

    View Slide

  66. @arnoutboks #dpc18
    A shot at fixing #67474: recap




    $doc = /* … (DOMDocument) */;
    $doc->getElementsByTagNameNS(
    "", "bar"
    )->length; // returns 0!

    View Slide

  67. @arnoutboks #dpc18
    A shot at fixing #67474
    php-src/ext/dom/
    • attr.c
    • document.c
    • dom_ce.h
    • dom_fe.h
    • element.c
    • node.c
    • php_dom.c
    • xpath.c
    • …

    View Slide

  68. @arnoutboks #dpc18
    A shot at fixing #67474
    const zend_function_entry php_dom_document_class_functions[] = {
    // ...
    PHP_FALIAS(createAttributeNS,
    dom_document_create_attribute_ns,
    arginfo_dom_document_create_attribute_ns)
    PHP_FALIAS(getElementsByTagNameNS,
    dom_document_get_elements_by_tag_name_ns,
    arginfo_dom_document_get_elements_by_tag_name_ns)
    PHP_FALIAS(getElementById, dom_document_get_element_by_id,
    arginfo_dom_document_get_element_by_id)
    // ...
    PHP_ME(domdocument, __construct,
    arginfo_dom_document_construct, ZEND_ACC_PUBLIC)
    PHP_FE_END
    };

    View Slide

  69. @arnoutboks #dpc18
    C macros

    View Slide

  70. @arnoutboks #dpc18
    C macros
    #define MIN(a,b) a < b ? a : b
    int c = MIN(42,7)
    // ^ is converted into
    // int c = 42 < 7 ? 42 : 7

    View Slide

  71. @arnoutboks #dpc18
    A shot at fixing #67474
    const zend_function_entry php_dom_document_class_functions[] = {
    // ...
    PHP_FALIAS(createAttributeNS,
    dom_document_create_attribute_ns,
    arginfo_dom_document_create_attribute_ns)
    PHP_FALIAS(getElementsByTagNameNS,
    dom_document_get_elements_by_tag_name_ns,
    arginfo_dom_document_get_elements_by_tag_name_ns)
    PHP_FALIAS(getElementById, dom_document_get_element_by_id,
    arginfo_dom_document_get_element_by_id)
    // ...
    PHP_ME(domdocument, __construct,
    arginfo_dom_document_construct, ZEND_ACC_PUBLIC)
    PHP_FE_END
    };

    View Slide

  72. @arnoutboks #dpc18
    A shot at fixing #67474
    PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns)
    {
    // ...
    if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
    "Oss", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) ==
    FAILURE) {
    return;
    }
    // ...
    local = xmlCharStrndup(name, name_len);
    nsuri = xmlCharStrndup(uri, uri_len);
    dom_namednode_iter(intern, 0, namednode, NULL, local, nsuri);
    }

    View Slide

  73. @arnoutboks #dpc18
    zend_parse_parameters (‘ZPP’)
    PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns)
    {
    // ...
    if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
    "Oss", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) ==
    FAILURE) {
    return;
    }
    // ...
    local = xmlCharStrndup(name, name_len);
    nsuri = xmlCharStrndup(uri, uri_len);
    dom_namednode_iter(intern, 0, namednode, NULL, local, nsuri);
    }
    s: string
    s: string
    O: object of given class

    View Slide

  74. @arnoutboks #dpc18
    zend_parse_parameters (‘ZPP’)
    Specifier Type
    a array
    b boolean
    d double/float
    l long/int
    o object (any type)
    O object (specific type)
    r resource
    s string
    z mixed

    View Slide

  75. @arnoutboks #dpc18
    zend_parse_parameters (‘ZPP’)
    Modifier Effect
    * variable number of arguments (0 or more)
    + variable number of arguments (1 or more)
    ! optional argument
    | remaining arguments are optional
    See README.PARAMETER_PARSING_API

    View Slide

  76. @arnoutboks #dpc18
    A shot at fixing #67474
    PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns)
    {
    // ...
    if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
    "Oss", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) ==
    FAILURE) {
    return;
    }
    // ...
    local = xmlCharStrndup(name, name_len);
    nsuri = xmlCharStrndup(uri, uri_len);
    dom_namednode_iter(intern, 0, namednode, NULL, local, nsuri);
    }

    View Slide

  77. @arnoutboks #dpc18
    A shot at fixing #67474
    xmlNode *dom_get_elements_by_tag_name_ns_raw(
    xmlNodePtr nodep, char *ns, char *local /* ... */
    ) { // ...
    if (
    ns == NULL ||
    (nodep->ns != NULL && (
    xmlStrEqual(nodep->ns->href, (xmlChar *)ns) ||
    xmlStrEqual((xmlChar *)"*", (xmlChar *)ns)
    ))
    ) { /* namespace matches */ } // ...
    }
    Eventually:

    View Slide

  78. @arnoutboks #dpc18
    A shot at fixing #67474
    xmlNode *dom_get_elements_by_tag_name_ns_raw(
    xmlNodePtr nodep, char *ns, char *local /* ... */
    ) { // ...
    if (
    ns == NULL ||
    (nodep->ns != NULL && (
    xmlStrEqual(nodep->ns->href, (xmlChar *)ns) ||
    xmlStrEqual((xmlChar *)"*", (xmlChar *)ns)
    ))
    ) { /* namespace matches */ } // ...
    }
    Eventually:
    element to ‘test’ filter namespace and
    local name

    View Slide

  79. @arnoutboks #dpc18
    A shot at fixing #67474
    xmlNode *dom_get_elements_by_tag_name_ns_raw(
    xmlNodePtr nodep, char *ns, char *local /* ... */
    ) { // ...
    if (
    ns == NULL ||
    (nodep->ns != NULL && (
    xmlStrEqual(nodep->ns->href, (xmlChar *)ns) ||
    xmlStrEqual((xmlChar *)"*", (xmlChar *)ns)
    ))
    ) { /* namespace matches */ } // ...
    }
    Eventually:
    “no namespace filter”

    View Slide

  80. @arnoutboks #dpc18
    A shot at fixing #67474
    xmlNode *dom_get_elements_by_tag_name_ns_raw(
    xmlNodePtr nodep, char *ns, char *local /* ... */
    ) { // ...
    if (
    ns == NULL ||
    (nodep->ns != NULL && (
    xmlStrEqual(nodep->ns->href, (xmlChar *)ns) ||
    xmlStrEqual((xmlChar *)"*", (xmlChar *)ns)
    ))
    ) { /* namespace matches */ } // ...
    }
    Eventually:
    “node has a namespace”, and
    “it matches the filter”
    or “filter is a wildcard”

    View Slide

  81. @arnoutboks #dpc18
    A shot at fixing #67474
    xmlNode *dom_get_elements_by_tag_name_ns_raw(
    xmlNodePtr nodep, char *ns, char *local /* ... */
    ) { // ...
    if (
    ns == NULL ||
    (nodep->ns == NULL && !strcmp(ns, "")) ||
    (nodep->ns != NULL && (
    xmlStrEqual(nodep->ns->href, (xmlChar *)ns) ||
    xmlStrEqual((xmlChar *)"*", (xmlChar *)ns)
    ))
    ) { /* namespace matches */ } // ...
    }
    Fix:
    “node has empty namespace”, and
    “filter is empty namespace”

    View Slide

  82. @arnoutboks #dpc18
    A shot at fixing #67474
    $ make test TESTS=ext/dom/tests/bug67474.phpt
    […]
    =============================================
    Running selected tests.
    PASS Bug #67474 getElementsByTagNameNS and
    default namespace [ext/dom/tests/bug67474.phpt]
    =============================================
    Number of tests : 1 1
    Tests passed : 1 (100.0%) (100.0%)

    View Slide

  83. @arnoutboks #dpc18
    PR for #67474
    Submit bug fixes to the oldest supported branch:
    http://php.net/supported-versions.php

    View Slide

  84. @arnoutboks #dpc18
    The Release Managers
    PHP
    7.1
    Davey Shafik
    @dshafik
    Joe Watkins
    @krakjoe
    PHP
    7.2
    Remi Collet
    @RemiCollet
    Sara Golemon
    @SaraMG
    PHP
    7.3
    Christoph M.
    Becker
    @cmbecker69
    Stanislav
    Malyshev
    @smalyshev

    View Slide

  85. @arnoutboks #dpc18
    PR for #67474: 2 hours later…

    View Slide

  86. @arnoutboks #dpc18
    It’s not THAT difficult
    • Read past the C details and macros
    • Focus on the logic
    • See where variables come from and go to
    • Try and see what happens
    • Rely on the tests

    View Slide

  87. @arnoutboks #dpc18
    You can do this!

    View Slide

  88. @arnoutboks #dpc18
    Bug fixes vs. features
    • Bug fixes
    • PR against oldest supported branch
    • No RFC needed
    • Refer to bug in bug tracker
    • Features
    • PR against master
    • Formal RFC needed

    View Slide

  89. @arnoutboks #dpc18
    RFC Process
    • Introduce idea, measure initial reaction
    • Formal proposal
    • Discussion period
    • Voting
    See https://wiki.php.net/rfc/howto &
    https://benramsey.com/talks/2015/06/dpc-contributing-core/

    View Slide

  90. @arnoutboks #dpc18
    Resources
    • http://php.net/internals
    • https://wiki.php.net/internals
    • https://wiki.php.net/internals/references
    • http://www.phpinternalsbook.com/
    • http://blog.jpauli.tech/
    • https://nikic.github.io/
    • https://blog.ircmaxell.com/search/label/PHP-Internals
    • https://www.sammyk.me/how-to-find-and-patch-a-
    bug-in-php-source-php-internals
    • https://externals.io

    View Slide

  91. @arnoutboks #dpc18
    Some time later…

    View Slide

  92. Documentation for PHP
    Contributing to the manual

    View Slide

  93. @arnoutboks #dpc18
    edit.php.net
    PHP Docbook Online Editor
    ‘Easiest’ way to get started
    (if you can figure out how it works)

    View Slide

  94. @arnoutboks #dpc18
    edit.php.net

    View Slide

  95. @arnoutboks #dpc18
    edit.php.net

    View Slide

  96. @arnoutboks #dpc18
    edit.php.net

    View Slide

  97. @arnoutboks #dpc18
    1. Find the correct file
    Under “All files” in the left menu
    Top-level directory per language
    • reference//
    • functions/.xml
    • .xml
    • /.xml
    • language/.xml

    View Slide

  98. @arnoutboks #dpc18
    1. Find the correct file
    Tip: Use the “edit” link from the documentation itself

    View Slide

  99. @arnoutboks #dpc18
    2. Make your changes
    Documentation is written using DocBook XML
    http://tdg.docbook.org/tdg/5.2/

    View Slide

  100. @arnoutboks #dpc18
    2. Make your changes
    Documentation is written using DocBook XML
    (or just peek in other docs)

    View Slide

  101. @arnoutboks #dpc18
    3. Preview changes
    Seems broken at the moment

    View Slide

  102. @arnoutboks #dpc18
    4. Submit as patch

    View Slide

  103. @arnoutboks #dpc18
    Tip: submit a docs patch
    instead of user note

    View Slide

  104. @arnoutboks #dpc18
    Don’t like edit.php.net?
    Make it better!

    View Slide

  105. @arnoutboks #dpc18
    Don’t like edit.php.net?
    Or set up your own development environment:
    https://www.sammyk.me/how-to-contribute-to-php-
    documentation

    View Slide

  106. @arnoutboks #dpc18
    Where to help?
    • Bugs of type “Doc” in bug tracker
    • check-missing-docs.php
    • “Failures to meet strict standards”
    (in edit.php.net sidebar)
    • Translations
    • Missing translations
    • Out-of-date translations
    • Translations needing review
    • Translations with errors

    View Slide

  107. @arnoutboks #dpc18
    Where to help?

    View Slide

  108. Recap
    Ways to contribute to PHP

    View Slide

  109. @arnoutboks #dpc18
    Numerous ways to contribute
    • Bug reports
    • Bug triaging
    • Running tests
    • Writing tests
    • Bug fixes
    • New features
    • Documentation patches
    • Documentation translations
    • Tools

    View Slide

  110. @arnoutboks #dpc18
    Why contribute?
    • Get ‘own’ bugs fixed
    • Fix ‘own’ bugs
    • Make PHP better
    • Make PHP more popular
    • Learn PHP
    • Learn C
    • Give back to the community

    View Slide

  111. @arnoutboks #dpc18
    You don’t have to be an expert
    to contribute to the PHP core

    View Slide

  112. @arnoutboks #dpc18
    Feedback & Questions
    @arnoutboks
    @arnoutboks
    @aboks
    Arnout Boks
    Please leave your feedback on joind.in:
    https://joind.in/talk/4783a

    View Slide

  113. @arnoutboks #dpc18
    Image Credits
    • https://photojournal.jpl.nasa.gov/jpeg/PIA19058.jpg
    • https://www.flickr.com/photos/vivianejl/22990832
    • https://www.flickr.com/photos/dhuiz/13609080315/
    • https://www.flickr.com/photos/gotovan/8671348572
    • https://www.flickr.com/photos/sidelong/246816211
    • https://www.flickr.com/photos/pezon64/23764268828
    • https://www.flickr.com/photos/crdot/6855538268/
    • https://www.flickr.com/photos/borkurdotnet/9682277597

    View Slide