From ade1dc23875b6ca90bbf97c68f73eacf19676c2d Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Fri, 2 Aug 2024 16:08:44 +0900 Subject: [PATCH] implement extension --- .devcontainer/devcontainer.json | 2 +- .github/renovate.json | 100 +++++++++++++++++++++++++++ .github/workflows/ci.yaml | 43 ++---------- .gitmodules | 4 ++ Dockerfile | 8 +++ README.md | 54 ++++----------- docker/mysql/etc/mysql/conf.d/my.cnf | 2 - ext/.gitignore | 44 ++++++++++++ ext/.gitkeep | 1 - ext/config.m4 | 22 ++++++ ext/extension_example.c | 83 ++++++++++++++++++++++ ext/extension_example.stub.php | 20 ++++++ ext/extension_example_arginfo.h | 40 +++++++++++ ext/php_extension_example.h | 31 +++++++++ ext/sodium.c | 100 +++++++++++++++++++++++++++ ext/sodium.h | 31 +++++++++ ext/tests/basic.phpt | 35 ++++++++++ ext/tests/engine.phpt | 12 ++++ ext/tests/extension.phpt | 10 +++ ext/third_party/libsodium | 1 + 20 files changed, 558 insertions(+), 85 deletions(-) create mode 100644 .github/renovate.json create mode 100644 .gitmodules delete mode 100644 docker/mysql/etc/mysql/conf.d/my.cnf create mode 100644 ext/.gitignore delete mode 100644 ext/.gitkeep create mode 100644 ext/config.m4 create mode 100644 ext/extension_example.c create mode 100644 ext/extension_example.stub.php create mode 100644 ext/extension_example_arginfo.h create mode 100644 ext/php_extension_example.h create mode 100644 ext/sodium.c create mode 100644 ext/sodium.h create mode 100644 ext/tests/basic.phpt create mode 100644 ext/tests/engine.phpt create mode 100644 ext/tests/extension.phpt create mode 160000 ext/third_party/libsodium diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b4c83b5..b4415e9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "name": "pskel", + "name": "extension_example", "customizations": { "vscode": { "extensions": [ diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..3428a13 --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,100 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ], + "timezone": "Asia/Tokyo", + "git-submodules": { + "enabled": true, + "versioning": "git", + "fileMatch": [ + "(^|/)\\.gitmodules$" + ] + }, + "packageRules": [ + { + "matchManagers": [ + "git-submodules" + ], + "enabled": false + }, + { + "matchDepNames": [ + "jedisct1/libsodium" + ], + "matchManagers": [ + "regex" + ], + "versioning": "regex:^(?\\d+)\\.(?\\d+)\\.(?\\d+)\\-RELEASE$", + "allowedVersions": "/^[0-9]+\\.[0-9]+\\.[0-9]+\\-RELEASE$/" + } + ], + "customManagers": [ + { + "customType": "regex", + "fileMatch": [ + "^\\.gitmodules$" + ], + "matchStrings": [ + "\\[submodule \"(?.+)\"\\][^\\[]*?\\n\\s*branch\\s*=\\s*(?.*)" + ], + "datasourceTemplate": "github-tags", + "versioningTemplate": "{{#if versioning}}{{versioning}}{{else}}semver{{/if}}" + } + ], + "postUpgradeTasks": { + "commands": [ + "(test \"{{{manager}}}\" = \"regex\" && git submodule update && git submodule init \"$(git config --file \".gitmodules\" submodule.{{{depName}}}.path)\" && git submodule update \"$(git config --file \".gitmodules\" submodule.{{{depName}}}.path)\" && (cd \"$(git config --file \".gitmodules\" submodule.{{{depName}}}.path)\" && git fetch --tags && git checkout \"{{{newVersion}}}\")) || true" + ] + } +} +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ], + "timezone": "Asia/Tokyo", + "git-submodules": { + "enabled": true, + "versioning": "git", + "fileMatch": [ + "(^|/)\\.gitmodules$" + ] + }, + "packageRules": [ + { + "matchManagers": [ + "git-submodules" + ], + "enabled": false + }, + { + "matchDepNames": [ + "jedisct1/libsodium" + ], + "matchManagers": [ + "regex" + ], + "versioning": "regex:^(?\\d+)\\.(?\\d+)\\.(?\\d+)\\-RELEASE$", + "allowedVersions": "/^[0-9]+\\.[0-9]+\\.[0-9]+\\-RELEASE$/" + } + ], + "customManagers": [ + { + "customType": "regex", + "fileMatch": [ + "^\\.gitmodules$" + ], + "matchStrings": [ + "\\[submodule \"(?.+)\"\\][^\\[]*?\\n\\s*branch\\s*=\\s*(?.*)" + ], + "datasourceTemplate": "github-tags", + "versioningTemplate": "{{#if versioning}}{{versioning}}{{else}}semver{{/if}}" + } + ], + "postUpgradeTasks": { + "commands": [ + "(test \"{{{manager}}}\" = \"regex\" && git submodule update && git submodule init \"$(git config --file \".gitmodules\" submodule.{{{depName}}}.path)\" && git submodule update \"$(git config --file \".gitmodules\" submodule.{{{depName}}}.path)\" && (cd \"$(git config --file \".gitmodules\" submodule.{{{depName}}}.path)\" && git fetch --tags && git checkout \"{{{newVersion}}}\")) || true" + ] + } +} diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 639d51c..da8062d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -6,12 +6,14 @@ jobs: strategy: matrix: arch: ["amd64", "arm64v8", "s390x"] - version: ["8.1", "8.2", "8.3"] + version: ["8.2", "8.3"] type: ["cli", "zts"] distro: ["bookworm", "alpine"] steps: - name: Checkout uses: actions/checkout@v4 + with: + submodules: true - name: Setup QEMU uses: docker/setup-qemu-action@v3 with: @@ -20,7 +22,7 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Build container run: | - docker compose build --pull --no-cache --build-arg IMAGE=${{ matrix.arch }}/php --build-arg TAG=${{ matrix.version }}-${{ matrix.type }}-${{ matrix.distro }} --build-arg PSKEL_SKIP_DEBUG=${{ matrix.arch != 'amd64' && '1' || '' }} + docker compose build --pull --no-cache --build-arg IMAGE=${{ matrix.arch }}/php --build-arg TAG=${{ matrix.version }}-${{ matrix.type }}-${{ matrix.distro }} --build-arg PSKEL_SKIP_DEBUG=${{ matrix.arch != 'amd64' && '1' || '' }} - name: Run tests run: | docker compose run --rm --entrypoint=/usr/bin/pskel_test --env TEST_EXTENSION=1 dev @@ -44,40 +46,3 @@ jobs: if: matrix.arch == 'amd64' && matrix.distro != 'alpine' run: | docker compose run --rm --entrypoint=/usr/bin/pskel_test --env TEST_EXTENSION_UBSAN=1 dev - # Windows: - # runs-on: windows-2022 - # defaults: - # run: - # shell: cmd - # strategy: - # matrix: - # arch: ["x64"] - # version: ["8.1", "8.2", "8.3"] - # ts: ["nts", "ts"] - # steps: - # - name: Checkout - # uses: actions/checkout@v4 - # - name: Setup PHP - # id: setup-php - # uses: php/setup-php-sdk@v0.8 - # with: - # arch: ${{ matrix.arch }} - # version: ${{ matrix.version }} - # ts: ${{ matrix.ts }} - # - name: Enable developer command prompt - # uses: ilammy/msvc-dev-cmd@v1 - # with: - # arch: ${{ matrix.arch }} - # toolset: ${{ steps.setup-php.outputs.toolset }} - # - name: phpize - # working-directory: ext - # run: phpize - # - name: configure - # working-directory: ext - # run: configure --enable-skeleton --with-prefix=${{ steps.setup-php.outputs.prefix }} - # - name: make - # working-directory: ext - # run: nmake - # - name: test - # working-directory: ext - # run: nmake test TESTS="--show-diff tests" diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..39045f2 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "jedisct1/libsodium"] + path = ext/third_party/libsodium + url = https://github.com/jedisct1/libsodium.git + branch = 1.0.20-RELEASE diff --git a/Dockerfile b/Dockerfile index 883dc20..de01e3f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -126,4 +126,12 @@ WORKDIR "/usr/src/php" COPY ./pskel_test.sh /usr/bin/pskel_test COPY ./pskel_init_extension.sh /usr/bin/pskel_init_extension +# Install libsodium +COPY ./ext/third_party/libsodium "/ext/third_party/libsodium" +RUN cd "/ext/third_party/libsodium" \ + && ./configure \ + && make -j"$(nproc)" \ + && make install \ + && cd - + COPY ./ext /ext diff --git a/README.md b/README.md index 22c9e21..98dafcf 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,23 @@ -# Pskel +# extension_example -A skeleton project for quickly setting up an environment to develop extensions for PHP. +[`zeriyoshi/pskel`](https://github.com/zeriyoshi/pskel) を用いた PHP Extension のサンプルです。 -### How to use +PHP 8.2 から利用できる `ext-random` ビルトイン拡張機能に [`libsodium`](https://github.com/jedisct1/libsodium) を用いた乱数生成器を追加するサンプル実装を含んでいます。 -1. Install [Visual Studio Code](https://code.visualstudio.com/) and Docker Desktop (or an alternative engine). -1. Install the [Remote Container](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension in VSCode. -1. Open the directory and open it with the `Remote Container` extension. -1. Run `pskel_init_extension` command. -2. Run `pskel_test` command for testing. - -### Q&A - -#### Can I set up an environment using MySQL, Redis, etc.? - -Yes. Pskel comes pre-setup with MySQL as a example. If you want to add something, you can easily do so by editing the `compose.yaml`. - -#### Can I use a debug version of PHP? - -A debug build of PHP is included in advance. Debug builds using GCC and Clang are available, and Valgrind support is enabled. With the Clang build, you can also use MemorySanitizer. - -They each have the following binary prefixes. The build toolchains are the same. - -- `debug-php` -- `gcc-valgrind-php` -- `clang-msan-php` -- `clang-asan-php` -- `clang-ubsan-php` - -For example, the method to test the extension using GCC + Valgrind is as follows: - -``` -# gcc-valgrind-phpize -# ./configure --with-php-config=$(which gcc-valgrind-php-config) -# TEST_PHP_ARGS="-q -m --show-diff" make -j$(nproc) test -``` - -#### Can I debug using gdb? - -Yes. Build using the debug version of PHP and run as follows: +### Usage ``` -# gdb --args gcc-valgrind-php -dextension=./modules/your_extension_name.so example.php +$ git clone --recursive "https://github.com/colopl/php-extension_example" "extension_example" +$ cd "extension_example/ext" +$ phpize && ./configure --with-php-config="$(which php-config)" +$ make -j"$(nproc)" && make test +$ [sudo] make install ``` -#### Can I develop using something other than Visual Studio Code? +### Development -While it's not recommended, it's possible. You can using Docker Compose (or a alternative engine). +このプロジェクトは [`zeriyoshi/pskel`](https://github.com/zeriyoshi/pskel) をベースに作成されています。基本的な使い方は Pskel と同様です。 -### License +### LICENSE PHP License 3.01 diff --git a/docker/mysql/etc/mysql/conf.d/my.cnf b/docker/mysql/etc/mysql/conf.d/my.cnf deleted file mode 100644 index e356587..0000000 --- a/docker/mysql/etc/mysql/conf.d/my.cnf +++ /dev/null @@ -1,2 +0,0 @@ -[mysqld] -default-authentication-plugin=mysql_native_password diff --git a/ext/.gitignore b/ext/.gitignore new file mode 100644 index 0000000..648b2b2 --- /dev/null +++ b/ext/.gitignore @@ -0,0 +1,44 @@ +*.lo +*.la +*.dep +.libs +acinclude.m4 +aclocal.m4 +autom4te.cache +build +config.guess +config.h +config.h.in +config.h.in~ +config.log +config.nice +config.status +config.sub +configure +configure~ +configure.ac +configure.in +include +install-sh +libtool +ltmain.sh +Makefile +Makefile.fragments +Makefile.global +Makefile.objects +missing +mkinstalldirs +modules +php_test_results_*.txt +phpt.* +run-test-info.php +run-tests.php +tests/**/*.diff +tests/**/*.out +tests/**/*.php +tests/**/*.exp +tests/**/*.log +tests/**/*.sh +tests/**/*.db +tests/**/*.mem +tmp-php.ini diff --git a/ext/.gitkeep b/ext/.gitkeep deleted file mode 100644 index 54793b1..0000000 --- a/ext/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -pskel_uninitialized \ No newline at end of file diff --git a/ext/config.m4 b/ext/config.m4 new file mode 100644 index 0000000..0e5b465 --- /dev/null +++ b/ext/config.m4 @@ -0,0 +1,22 @@ +dnl config.m4 for extension_example extension + +PHP_ARG_WITH([extension_example], [for extension_example support], [AS_HELP_STRING([--with-extension_example]), [Include extension_example support]]) + +if test "${PHP_EXTENSION_EXAMPLE}" != "no"; then + dnl check for required libraries and headers + AC_CHECK_LIB([sodium], [sodium_version_string], [], [ + AC_MSG_ERROR([Required library sodium not found. Please install libsodium library]) + ]) + + AC_CHECK_HEADER([sodium.h], [], [ + AC_MSG_ERROR([Required header sodium.h not found. Please install libsodium library]) + ]) + + PHP_ADD_INCLUDE("/usr/local/include") + PHP_ADD_LIBRARY_WITH_PATH(sodium, "/usr/local/lib", EXTENSION_EXAMPLE_SHARED_LIBADD) + + PHP_SUBST(EXTENSION_EXAMPLE_SHARED_LIBADD) + PHP_SUBST(EXTENSION_EXAMPLE_LIBS) + + PHP_NEW_EXTENSION(extension_example, extension_example.c sodium.c, $ext_shared) +fi diff --git a/ext/extension_example.c b/ext/extension_example.c new file mode 100644 index 0000000..b16de97 --- /dev/null +++ b/ext/extension_example.c @@ -0,0 +1,83 @@ +/* + +----------------------------------------------------------------------+ + | COLOPL Extension Example. | + +----------------------------------------------------------------------+ + | Copyright (c) COLOPL, Inc. | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | info@colopl.co.jp so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Go Kudo | + +----------------------------------------------------------------------+ +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "php.h" +#include "ext/standard/info.h" + +#include "php_extension_example.h" +#include "extension_example_arginfo.h" + +#include "sodium.h" + +#include + +ZEND_FUNCTION(Colopl_ExtensionExample_get_sodium_version) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + RETURN_STRING(sodium_version_string()); +} + +PHP_MINIT_FUNCTION(extension_example) +{ + if (register_sodium_class() == NULL) { + return FAILURE; + } + + return SUCCESS; +} + +PHP_RINIT_FUNCTION(extension_example) +{ +#if defined(ZTS) && defined(COMPILE_DL_EXTENSION_EXAMPLE) + ZEND_TSRMLS_CACHE_UPDATE(); +#endif + + return SUCCESS; +} + +PHP_MINFO_FUNCTION(extension_example) +{ + php_info_print_table_start(); + php_info_print_table_row(2, "extension_example support", "enabled"); + php_info_print_table_end(); +} + +zend_module_entry extension_example_module_entry = { + STANDARD_MODULE_HEADER, + "extension_example", + ext_functions, + PHP_MINIT(extension_example), + NULL, + PHP_RINIT(extension_example), + NULL, + PHP_MINFO(extension_example), + PHP_EXTENSION_EXAMPLE_VERSION, + STANDARD_MODULE_PROPERTIES +}; + +#ifdef COMPILE_DL_EXTENSION_EXAMPLE +# ifdef ZTS +ZEND_TSRMLS_CACHE_DEFINE() +# endif +ZEND_GET_MODULE(extension_example) +#endif diff --git a/ext/extension_example.stub.php b/ext/extension_example.stub.php new file mode 100644 index 0000000..4caac2c --- /dev/null +++ b/ext/extension_example.stub.php @@ -0,0 +1,20 @@ +ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + zend_class_implements(class_entry, 1, class_entry_Random_Engine); + + return class_entry; +} diff --git a/ext/php_extension_example.h b/ext/php_extension_example.h new file mode 100644 index 0000000..1d8850b --- /dev/null +++ b/ext/php_extension_example.h @@ -0,0 +1,31 @@ +/* + +----------------------------------------------------------------------+ + | COLOPL Extension Example. | + +----------------------------------------------------------------------+ + | Copyright (c) COLOPL, Inc. | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | info@colopl.co.jp so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Go Kudo | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_EXTENSION_EXAMPLE_H +# define PHP_EXTENSION_EXAMPLE_H + +extern zend_module_entry extension_example_module_entry; +# define phpext_extension_example_ptr &extension_example_module_entry + +# define PHP_EXTENSION_EXAMPLE_VERSION "0.1.0" + +# if defined(ZTS) && defined(COMPILE_DL_EXTENSION_EXAMPLE) +ZEND_TSRMLS_CACHE_EXTERN() +# endif + +#endif /* PHP_EXTENSION_EXAMPLE_H */ diff --git a/ext/sodium.c b/ext/sodium.c new file mode 100644 index 0000000..35b2a89 --- /dev/null +++ b/ext/sodium.c @@ -0,0 +1,100 @@ +/* + +----------------------------------------------------------------------+ + | COLOPL Extension Example. | + +----------------------------------------------------------------------+ + | Copyright (c) COLOPL, Inc. | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | info@colopl.co.jp so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Go Kudo | + +----------------------------------------------------------------------+ +*/ + +#include "php.h" +#include "ext/random/php_random.h" + +#include "php_extension_example.h" +#include "extension_example_arginfo.h" + +#include "sodium.h" + +#include +#include + +static zend_object_handlers sodium_object_handlers; +static zend_class_entry *sodium_ce; + +static uint64_t generate(php_random_status *status) { + uint64_t buf; + + randombytes_buf(&buf, sizeof(uint64_t)); + + return buf; +} + +static zend_long range(php_random_status *status, zend_long min, zend_long max) { + return php_random_range(&extension_example_algo_sodium, status, min, max); +} + +PHPAPI const php_random_algo extension_example_algo_sodium = { + sizeof(zend_ulong), + sizeof(zend_long), + NULL, + generate, + range, + NULL, + NULL +}; + +static zend_object *sodium_create_object(zend_class_entry *ce) { + php_random_engine *engine = php_random_engine_common_init(ce, &sodium_object_handlers, &extension_example_algo_sodium); + + (*(zend_long *)engine->status) = 0; + + return &engine->std; +} + +zend_class_entry *register_sodium_class() { + sodium_ce = register_class_Colopl_ExtensionExample_Sodium(random_ce_Random_Engine); + sodium_ce->create_object = sodium_create_object; + memcpy(&sodium_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + sodium_object_handlers.offset = XtOffsetOf(php_random_engine, std); + sodium_object_handlers.free_obj = php_random_engine_common_free_object; + sodium_object_handlers.clone_obj = NULL; /* Can't clonable */ + + return sodium_ce; +} + +ZEND_METHOD(Colopl_ExtensionExample_Sodium, generate) +{ + php_random_engine *engine = Z_RANDOM_ENGINE_P(ZEND_THIS); + uint64_t generated; + zend_string *bytes; + + ZEND_PARSE_PARAMETERS_NONE(); + + generated = engine->algo->generate(NULL); + (*(zend_long *) engine->status)++; + bytes = zend_string_alloc(engine->algo->generate_size, false); + for (size_t i = 0; i < engine->algo->generate_size; i++) { + ZSTR_VAL(bytes)[i] = (generated >> (i * 8) & 0xff); + } + ZSTR_VAL(bytes)[engine->algo->generate_size] = '\0'; + + RETURN_STR(bytes); +} + +ZEND_METHOD(Colopl_ExtensionExample_Sodium, getCallCount) +{ + php_random_engine *engine = Z_RANDOM_ENGINE_P(ZEND_THIS); + + ZEND_PARSE_PARAMETERS_NONE(); + + RETURN_LONG((*(zend_long *) engine->status)); +} diff --git a/ext/sodium.h b/ext/sodium.h new file mode 100644 index 0000000..27894b4 --- /dev/null +++ b/ext/sodium.h @@ -0,0 +1,31 @@ +/* + +----------------------------------------------------------------------+ + | COLOPL Extension Example. | + +----------------------------------------------------------------------+ + | Copyright (c) COLOPL, Inc. | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | info@colopl.co.jp so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Go Kudo | + +----------------------------------------------------------------------+ +*/ + +#ifndef SODIUM_H +# define SODIUM_H + +# include "php.h" +# include "ext/random/php_random.h" + +# include + +extern PHPAPI const php_random_algo extension_example_algo_sodium; + +zend_class_entry *register_sodium_class(); + +#endif /* SODIUM_H */ diff --git a/ext/tests/basic.phpt b/ext/tests/basic.phpt new file mode 100644 index 0000000..2bf9dce --- /dev/null +++ b/ext/tests/basic.phpt @@ -0,0 +1,35 @@ +--TEST-- +extension_example basic test +--FILE-- +getCallCount(), \PHP_EOL; +$test->generate(); + +echo $test->getCallCount(), \PHP_EOL; +$test->generate(); + +echo $test->getCallCount(), \PHP_EOL; +$test->generate(); + +$test = new \Colopl\ExtensionExample\Sodium(); +echo $test->getCallCount(), \PHP_EOL; +$test->generate(); + +echo \Colopl\ExtensionExample\get_sodium_version(), \PHP_EOL; + +try { + \serialize(new \Colopl\ExtensionExample\Sodium()); +} catch (\Exception $e) { + echo $e->getMessage(), \PHP_EOL; +} + +?> +--EXPECTF-- +0 +1 +2 +0 +%d.%d.%d +Serialization of 'Colopl\ExtensionExample\Sodium' is not allowed diff --git a/ext/tests/engine.phpt b/ext/tests/engine.phpt new file mode 100644 index 0000000..263c30e --- /dev/null +++ b/ext/tests/engine.phpt @@ -0,0 +1,12 @@ +--TEST-- +extension_example engine test +--FILE-- +nextInt(), \PHP_EOL; + +?> +--EXPECTF-- +%d diff --git a/ext/tests/extension.phpt b/ext/tests/extension.phpt new file mode 100644 index 0000000..5e6e90f --- /dev/null +++ b/ext/tests/extension.phpt @@ -0,0 +1,10 @@ +--TEST-- +Check if extension_example is loaded +--FILE-- + +--EXPECT-- +The extension "extension_example" is available diff --git a/ext/third_party/libsodium b/ext/third_party/libsodium new file mode 160000 index 0000000..9511c98 --- /dev/null +++ b/ext/third_party/libsodium @@ -0,0 +1 @@ +Subproject commit 9511c982fb1d046470a8b42aa36556cdb7da15de