🐘

[PHP] joinはimplodeのaliasだが、それはZend APIのmacro定義で実現している

2020/12/17に公開

PHPにおける join は implode の alias である。

このaliasがどのように内部で実現されているかについて軽く紹介する。タイトルのとおりなのでそれ以上の情報はない。

join

下記仕様ドキュメントにあるが、これは implode() の alias である。

https://www.php.net/manual/en/function.join.php

join — Alias of implode()

phptを手に取るとこういうテストによってそのふるまいは確かめられている。

--TEST--
Test join() function : basic functionality
--FILE--
<?php
echo "*** Testing join() : basic functionality ***\n";

// Initialize all required variables
$glue = ',';
$pieces = array(1, 2, 3, 4);

// pieces as array with numeric values
var_dump( join($glue, $pieces) );

// pieces as array with strings values
$glue = ", "; // multiple car as glue
$pieces = array("Red", "Green", "Blue", "Black", "White");
var_dump( join($glue, $pieces) );

// pieces as associative array (numeric values)
$pieces = array("Hour" => 10, "Minute" => 20, "Second" => 40);
$glue = ':';
var_dump( join($glue, $pieces) );

// pieces as associative array (string/numeric values)
$pieces = array("Day" => 'Friday', "Month" => "September", "Year" => 2007);
$glue = '/';
var_dump( join($glue, $pieces) );

echo "Done\n";
?>
--EXPECT--
*** Testing join() : basic functionality ***
string(7) "1,2,3,4"
string(30) "Red, Green, Blue, Black, White"
string(8) "10:20:40"
string(21) "Friday/September/2007"
Done

https://github.com/php/php-src/blob/83b26c612780f3c13d53e35b8bb895602b2597ae/ext/standard/tests/strings/join_basic.phpt#L2

ext/standards

join関数は、php-src内の ext/standards 内で定義されている。

	ZEND_FE(implode, arginfo_implode)
	ZEND_FALIAS(join, implode, arginfo_join) // ここでalias登録されている。
	ZEND_FE(strtok, arginfo_strtok)
	ZEND_FE(strtoupper, arginfo_strtoupper)
	ZEND_FE(strtolower, arginfo_strtolower)

https://github.com/php/php-src/blob/73321bc300c808346b2d00ec1bc513447a5d579b/ext/standard/basic_functions_arginfo.h#L3091

ZEND_FALIASがなにかについては、次のZend APIの内部仕様についての解説にて記載されている。ZEND_FALIASというマクロが定義されている。

https://www.php.net/manual/en/internals2.ze1.zendapi.php#internals2.ze1.zendapi.tab.funcdef-macros

ZEND_FALIAS(name, alias, arg_types): Defines an alias named alias for name. arg_types needs to be set to NULL. Doesn't require a corresponding C function; refers to the alias target instead.

※ 当サイトにあるとおり「This information is currently rather outdated, parts of it only cover early stages of the ZendEngine 1.0 API as it was used in early versions of PHP 4.」とあるため、すべての情報が正しいわけではないことを留意。

そのマクロを利用することでエイリアス登録できるという機能となる。

(しれっとfix typoをまた送った。 https://github.com/php/php-src/pull/6519

Discussion