PhpGenerics

这里是龙。(Here be dragons)

  • 所有者: ircmaxell/PhpGenerics
  • 平台: Linux, Mac, Windows
  • 許可證:
  • 分類:
  • 主題:
  • 喜歡:
    0
      比較:

Github星跟蹤圖

Muahahahahahahaha

I'll let the example speak for itself:

Example:

Test/Item.php

namespace test;

class Item<T> {
    
    protected $item;
    
    public function __construct(T $item = null)
    {
        $this->item = $item;
    }

    public function getItem()
    {
        return $item;
    }

    public function setItem(T $item)
    {
        $this->item = $item;
    }
}

Test/Test.php

namespace Test;

class Test {
    public function runTest()
    {
        $item = new Item<StdClass>;
        var_dump($item instanceof Item); // true
        $item->setItem(new StdClass); // works fine
        // $item->setItem([]); // E_RECOVERABLE_ERROR
    }
}

test.php

require "vendor/autoload.php";

$test = new Test\Test;
$test->runTest();

HOW???

Black magic and voodoo.

Where can I use generics?

Right now, only class definitions can define generics, and any parameter or return type declaration can use them.

It also supports parameter-expansion:

class Foo<T> {
    public function bar(): Foo<T> {}
}

As far as the rest, I don't know.

Seriously, How???

Like I said, black magic. If you want to know, you're going to regret it.

How do I install?

Since this is black voodoo evilness, I'm not adding it to packagist. Simply add a composer repository pointing here, and composer install. Then just use generics in your code and be happy.

HOW ARE YOU DOING THIS?

You really don't want to know...

Gotchas

Right now, generic types are not resolved according to use rules. So

    new Item<StdClass>

Always points to \StdClass. It will not respect use or the present namespace. This is a TODO.

FOR THE LOVE OF GOD, HOW???

Fine. Your loss.

I hijack the composer autoloader, and substitute my own. I then pre-process all autoloaded files, transpiling them to eliminate generics from declarations. I also compile usages from generic syntax to namespace syntax (compiling the types as we go along).

So:

new Item<StdClass>

Becomes

new Item\①StdClass①

Then, the autoloader recognizes attempts to load these classes and will generate the templated code... The above 2 blocks of code will be compiled to:

class test
{
    public function runTests()
    {
        $item = new \test\Item\①StdClass①(new \StdClass());
        $itemList = new \test\ItemList\①StdClass①();
        $itemList->addItem($item);
    }
}

And:

namespace test\Item;

class ①StdClass① extends \test\Item
{
    protected $item;

    public function __construct(\StdClass $item)
    {
        $this->item = $item;
    }

    public function getItem()
    {
        return $item;
    }
    
    public function setItem(\StdClass $item)
    {
        $this->item = $item;
    }
}

TL;DR

TL;DR: don't use this

主要指標

概覽
名稱與所有者ircmaxell/PhpGenerics
主編程語言PHP
編程語言PHP (語言數: 1)
平台Linux, Mac, Windows
許可證
所有者活动
創建於2015-03-27 22:09:14
推送於2015-04-01 21:26:59
最后一次提交2015-04-01 17:26:59
發布數0
用户参与
星數556
關注者數18
派生數12
提交數14
已啟用問題?
問題數8
打開的問題數5
拉請求數5
打開的拉請求數0
關閉的拉請求數0
项目设置
已啟用Wiki?
已存檔?
是復刻?
已鎖定?
是鏡像?
是私有?