LoginSignup
11
10

More than 5 years have passed since last update.

PHPで関数や定数のオートロード

Posted at

無理やりの実装です。
正直、使いドコロはないと考えています…

関数やネームスペースはオートロードすることが出来ない

関数やネームスペースはオートロード出来ないため、以下のコードはエラーになる。

Functions.php
namespace Functions
{
    function foo
    {
        echo 'foo' . PHP_EOL;
    }
}
index.php
$loader = include 'path/to/vendor/autoload.php';
$loader->set('', __DIR__);

use function \Functions\foo;
foo(); // Fatal error: Call to undefined function \Functions\foo

関数を定義したネームスペースに無理やりクラスを定義してオートロードを実現する

クラスならオートロード可能なので、関数を定義したネームスペース内にファイルをロードするためのクラスを定義する。

Functions/Foo.php
namespace Functions
{
    class Foo
    {
        public static function load() {}
    }

    function foo
    {
        echo 'foo' . PHP_EOL;
    }
}
index.php
$loader = include 'path/to/vendor/autoload.php';
$loader->set('', __DIR__);

use \Functions\Foo;
Foo::load();
\Functions\foo(); // "foo"

上記の例は関数のみを名前空間に定義しているが、定数を定義することも出来る。
実のところ、loadメソッドを呼ばなければならないでオートロードではない。

利用サンプル

以下はGinqで関数のオートロードを利用した例。

Functions/CallbackFilter.php
namespace Functions
{
    class CallbackFilter
    {
        public static functioni load() {}
    }

    /**
     * @params int $v
     * @return bool
     */
    function filterOdd($v)
    {
        return ($v % 2 !== 0);
    }
}
index.php
$loader = include 'path/to/vendor/autoload.php';
$loader->set('', __DIR__);

\Functions\CallbackFilter::load();
$xs = Ginq::from([1,2,3,4,5])->filter('\\Functions\\filterOdd');
foreach ($xs as $x) {
    echo $x . PHP_EOL;
}
// 1
// 3
// 5

まとめ

冒頭で使いドコロはないとかいていますが、その理由としてphpのcallable型は['class-name', 'method-name']と指定することでクラス内のメソッドを呼び出す事が出来るという点にあります。
この投稿であげた方法はPHPデフォルトの挙動をわざわざ回りくどい方法を使って解決しているだけなんですね。
デフォルトの機能を投げ打ってまで実装する必要は無いです;;

関数やら定数のインポートなんて機能は無理やり使うと余計に分かりにくいプログラムが誕生するようなきがするので、なんで実装したのか疑問でなりません。

11
10
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10