Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions EXTENSIONS
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,12 @@ MAINTENANCE: Maintained
STATUS: Working
SINCE: 8.5.0
-------------------------------------------------------------------------------
EXTENSION: uuid
PRIMARY MAINTAINER Máté Kocsis <kocsismate@php.net> (2026 - 2026)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 8.6.0
-------------------------------------------------------------------------------
EXTENSION: zip
PRIMARY MAINTAINER: Pierre-Alain Joye <pajoye@php.net> (2006 - 2011)
Remi Collet <remi@php.net> (2013-2020)
Expand Down
1 change: 1 addition & 0 deletions UPGRADING.INTERNALS
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ PHP 8.6 INTERNALS UPGRADE NOTES
ZEND_AST_TRAIT_METHOD_REFERENCE.
. The EMPTY_SWITCH_DEFAULT_CASE() macro has been removed. Use
default: ZEND_UNREACHABLE(); instead.
. Introduced a new time-retrieval API zend_time_*.

========================
2. Build system changes
Expand Down
55 changes: 55 additions & 0 deletions Zend/zend_time.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| 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: |
| https://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 |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Marc Bennewitz <marc@mabe.berlin> |
+----------------------------------------------------------------------+
*/

#include "zend_time.h"

/* Current real/wall-time in seconds */
ZEND_API time_t zend_time_real_sec(void) {
return time(NULL);
}

ZEND_API void zend_time_real_spec(struct timespec *ts) {
#if defined(HAVE_CLOCK_GETTIME)

(void) clock_gettime(CLOCK_REALTIME, ts);

#elif defined(HAVE_TIMESPEC_GET)

(void) timespec_get(ts, TIME_UTC);

#elif defined(HAVE_GETTIMEOFDAY)

struct timeval tv;
(void) gettimeofday(&tv, NULL);
zend_time_val2spec(tv, ts);

#else

ts->tv_sec = zend_time_real_get();
Comment thread
kocsismate marked this conversation as resolved.
ts->tv_nsec = 0;

#endif
}

ZEND_API uint64_t zend_time_mono_fallback_nsec(void) {
#if ZEND_HRTIME_AVAILABLE
return (uint64_t)zend_hrtime();
#else
struct timespec ts;
zend_time_real_spec(&ts);
return ((uint64_t) ts.tv_sec * ZEND_NANO_IN_SEC) + ts.tv_nsec;
#endif
}
95 changes: 95 additions & 0 deletions Zend/zend_time.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| 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: |
| https://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 |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Marc Bennewitz <marc@mabe.berlin> |
+----------------------------------------------------------------------+
*/

#ifndef ZEND_TIME_H
#define ZEND_TIME_H

#include "zend_portability.h"

#ifdef PHP_WIN32
# include "win32/time.h"
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <time.h>

#include "zend_hrtime.h"

#ifndef PHP_WIN32
# define tv_sec_t time_t
# define tv_usec_t suseconds_t
#else
# define tv_sec_t long
# define tv_usec_t long
#endif

#define ZEND_MILLI_IN_SEC 1000U
#define ZEND_MICRO_IN_SEC 1000000U

BEGIN_EXTERN_C()

/* Assign seconds to timeval */
static zend_always_inline void zend_time_sec2val(time_t s, struct timeval *tv) {
tv->tv_sec = (tv_sec_t) s;
tv->tv_usec = 0;
}

/* Assign microseconds to timeval */
static zend_always_inline void zend_time_usec2val(int64_t usec, struct timeval *tv) {
tv->tv_sec = (tv_sec_t) (usec / ZEND_MICRO_IN_SEC);
tv->tv_usec = (tv_usec_t) (usec % ZEND_MICRO_IN_SEC);

if (UNEXPECTED(tv->tv_usec < 0)) {
tv->tv_usec += ZEND_MICRO_IN_SEC;
tv->tv_sec -= 1;
}
}

/* Assign double (seconds) to timeval */
static zend_always_inline void zend_time_dbl2val(double s, struct timeval *tv) {
tv->tv_sec = (tv_sec_t) s;
tv->tv_usec = (tv_usec_t) ((s - tv->tv_sec) * ZEND_MICRO_IN_SEC);

if (UNEXPECTED(tv->tv_usec < 0)) {
tv->tv_usec += ZEND_MICRO_IN_SEC;
tv->tv_sec -= 1;
} else if (UNEXPECTED(tv->tv_usec >= ZEND_MICRO_IN_SEC)) {
// rare, but protects against rounding up to exactly 1 second
tv->tv_usec -= ZEND_MICRO_IN_SEC;
tv->tv_sec += 1;
}
}

/* Assign timeval to timespec */
static zend_always_inline void zend_time_val2spec(struct timeval tv, struct timespec *ts) {
ts->tv_sec = (time_t) tv.tv_sec;
ts->tv_nsec = (long) (tv.tv_usec * 1000);
}

/* Current real/wall-time in seconds */
ZEND_API time_t zend_time_real_sec(void);

/* Current real/wall-time in up-to nano seconds */
ZEND_API void zend_time_real_spec(struct timespec *ts);

/* Monotonic time in nanoseconds with a fallback to real/wall-time
if no monotonic timer is available */
ZEND_API uint64_t zend_time_mono_fallback_nsec(void);

END_EXTERN_C()

#endif // ZEND_TIME_H
3 changes: 3 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,7 @@ AC_CHECK_FUNCS(m4_normalize([
asctime_r
asprintf
chroot
clock_gettime
ctime_r
explicit_memset
fdatasync
Expand Down Expand Up @@ -598,6 +599,7 @@ AC_CHECK_FUNCS(m4_normalize([
strptime
strtok_r
symlink
timespec_get
tzset
unsetenv
usleep
Expand Down Expand Up @@ -1754,6 +1756,7 @@ PHP_ADD_SOURCES([Zend], m4_normalize([
zend_generators.c
zend_hash.c
zend_highlight.c
zend_time.c
zend_hrtime.c
zend_inheritance.c
zend_ini_parser.c
Expand Down
1 change: 1 addition & 0 deletions ext/standard/credits_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ CREDIT_LINE("System V Shared Memory", "Christian Cartus");
CREDIT_LINE("tidy", "John Coggeshall, Ilia Alshanetsky");
CREDIT_LINE("tokenizer", "Andrei Zmievski, Johannes Schlueter");
CREDIT_LINE("uri", "Máté Kocsis, Tim Düsterhus, Ignace Nyamagana Butera, Arnaud Le Blanc, Dennis Snell, Niels Dossche, Nicolas Grekas");
CREDIT_LINE("uuid", "Máté Kocsis");
CREDIT_LINE("XML", "Stig Bakken, Thies C. Arntzen, Sterling Hughes");
CREDIT_LINE("XMLReader", "Rob Richards");
CREDIT_LINE("XMLWriter", "Rob Richards, Pierre-Alain Joye");
Expand Down
2 changes: 2 additions & 0 deletions ext/uuid/CREDITS
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
uuid
Máté Kocsis
7 changes: 7 additions & 0 deletions ext/uuid/benchmark/7_php_uuid.expectation
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
X-Powered-By: PHP/%v
Content-type: text/html; charset=UTF-8

object(Uuid\UuidV7)#%d (%d) {
["uuid"]=>
string(36) "%s-%s-%s-%s-%s"
}
8 changes: 8 additions & 0 deletions ext/uuid/benchmark/7_php_uuid.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
TEST_NAME="PHP UUID"
TEST_ID=php_uuid
TEST_WARMUP=20
TEST_ITERATIONS=50
TEST_REQUESTS=10

TEST_TYPE=micro
TEST_FILE=config/test/7_php_uuid.php
7 changes: 7 additions & 0 deletions ext/uuid/benchmark/7_php_uuid.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

for ($i = 0; $i < 50_000; $i++) {
$uuid = Uuid\UuidV7::generate();
}

var_dump($uuid);
7 changes: 7 additions & 0 deletions ext/uuid/benchmark/8_symfony_uuid.expectation
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
X-Powered-By: PHP/%v
Content-type: text/html; charset=UTF-8

object(Symfony\Component\Uid\UuidV7)#%d (%d) {
["uid":protected]=>
string(36) "%s-%s-%s-%s-%s"
}
8 changes: 8 additions & 0 deletions ext/uuid/benchmark/8_symfony_uuid.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
TEST_NAME="Symfony UUID"
TEST_ID=symfony_uuid
TEST_WARMUP=20
TEST_ITERATIONS=50
TEST_REQUESTS=10

TEST_TYPE=micro
TEST_FILE=config/test/8_symfony_uuid.php
9 changes: 9 additions & 0 deletions ext/uuid/benchmark/8_symfony_uuid.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

require_once __DIR__ . "/../../app/symfony_uuid/vendor/autoload.php";

for ($i = 0; $i < 50_000; $i++) {
$uuid = new Symfony\Component\Uid\UuidV7();
}

var_dump($uuid);
22 changes: 22 additions & 0 deletions ext/uuid/benchmark/8_symfony_uuid_install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -e

symfony_version="8.0.8"
symfony_dir="$PROJECT_ROOT/app/symfony_uuid"

if [[ -d "$symfony_dir" ]]; then
echo "symfony/uid is already installed"
exit
fi

mkdir -p "$symfony_dir"

sudo docker run --rm \
--volume $PROJECT_ROOT:/code \
--user $(id -u):$(id -g) \
setup bash -c "\
set -e \
[[ -n '$GITHUB_TOKEN' ]] && composer config --global github-oauth.github.com '$GITHUB_TOKEN'; \
composer require symfony/uid:$symfony_version --ignore-platform-reqs --no-interaction --working-dir=/code/app/symfony_uuid && \
composer config platform-check false --working-dir=/code/app/symfony_uuid && \
composer dump-autoload --classmap-authoritative --no-interaction --working-dir=/code/app/symfony_uuid"
9 changes: 9 additions & 0 deletions ext/uuid/benchmark/9_ramsey_uuid.expectation
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
X-Powered-By: PHP/%v
Content-type: text/html; charset=UTF-8

object(Ramsey\Uuid\Lazy\LazyUuidFromString)#%d (%d) {
["unwrapped":"Ramsey\Uuid\Lazy\LazyUuidFromString":private]=>
NULL
["uuid":"Ramsey\Uuid\Lazy\LazyUuidFromString":private]=>
string(36) "%s-%s-%s-%s-%s"
}
8 changes: 8 additions & 0 deletions ext/uuid/benchmark/9_ramsey_uuid.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
TEST_NAME="Ramsey UUID"
TEST_ID=ramsey_uuid
TEST_WARMUP=20
TEST_ITERATIONS=50
TEST_REQUESTS=10

TEST_TYPE=micro
TEST_FILE=config/test/9_ramsey_uuid.php
9 changes: 9 additions & 0 deletions ext/uuid/benchmark/9_ramsey_uuid.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

require_once __DIR__ . "/../../app/ramsey_uuid/vendor/autoload.php";

for ($i = 0; $i < 50_000; $i++) {
$uuid = Ramsey\Uuid\Uuid::uuid7();
}

var_dump($uuid);
22 changes: 22 additions & 0 deletions ext/uuid/benchmark/9_ramsey_uuid_install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -e

ramsey_version="4.9.2"
ramsey_dir="$PROJECT_ROOT/app/ramsey_uuid"

if [[ -d "$ramsey_dir" ]]; then
echo "ramsey/uuid is already installed"
exit
fi

mkdir -p "$ramsey_dir"

sudo docker run --rm \
--volume $PROJECT_ROOT:/code \
--user $(id -u):$(id -g) \
setup bash -c "\
set -e \
[[ -n '$GITHUB_TOKEN' ]] && composer config --global github-oauth.github.com '$GITHUB_TOKEN'; \
composer require ramsey/uuid:$ramsey_version --ignore-platform-reqs --no-interaction --working-dir=/code/app/ramsey_uuid && \
composer config platform-check false --working-dir=/code/app/ramsey_uuid && \
composer dump-autoload --classmap-authoritative --no-interaction --working-dir=/code/app/ramsey_uuid"
11 changes: 11 additions & 0 deletions ext/uuid/config.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
dnl Configure options
dnl

PHP_INSTALL_HEADERS([ext/uuid], m4_normalize([
php_uuid.h
uuidv7-h/php_uuid.h
Comment thread
kocsismate marked this conversation as resolved.
Outdated
]))

PHP_NEW_EXTENSION(uuid, [php_uuid.c], [no],,[-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
PHP_ADD_EXTENSION_DEP(uuid, date)
PHP_ADD_EXTENSION_DEP(uuid, random)
7 changes: 7 additions & 0 deletions ext/uuid/config.w32
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
EXTENSION("uuid", "php_uuid.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");

ADD_FLAG("CFLAGS_UUID", "/D UUID_STATIC_BUILD");

ADD_EXTENSION_DEP("uuid", "date");
ADD_EXTENSION_DEP("uuid", "random");
PHP_INSTALL_HEADERS("ext/uuid", "php_uuid.h uuidv7-h/uuidv7.h");
Loading
Loading