Skip to content

Instantly share code, notes, and snippets.

@hikari-no-yume
Created March 20, 2017 20:02
Show Gist options
  • Star 72 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save hikari-no-yume/33cf828bfa306b1b1d2187a6de639375 to your computer and use it in GitHub Desktop.
Save hikari-no-yume/33cf828bfa306b1b1d2187a6de639375 to your computer and use it in GitHub Desktop.
function chaining for PHP 7
<?php declare(strict_types=1);
require_once "✨.🐘";
✨($_)->strlen("foo")->var_dump($_);
<?php declare(strict_types=1);
function ✨(&$_) {
return new class($_) {
private $_;
public function __construct(&$_) {
$this->_ = &$_;
}
public function __call(string $name, array $args): self {
$this->_ = $name(...$args);
return $this;
}
};
}
@sgolemon
Copy link

sgolemon commented Mar 20, 2017

A comparison of usages

Traditional:

$result = strtolower(str_rot13(file_get_contents("/tmp/foo"))));

PipeOp (HackLang):

$result = file_get_contents("/tmp/foo")
  |> str_rot13($$)
  |> strtolower($$);

Magic:

✨($_)->file_get_contents("/tmp/foo")
  ->str_rot13($_)
  ->strtolower($_);
$result = $_;

@anovsiradj
Copy link

Awesome!

@Potherca
Copy link

That... is genius!

On a side-note, the same is possible in PHP 5.6 (albeit without an anonymous class):

I've had to change the class name as Gist complains: You can't comment at this time — your comment contains unicode characters above 0xffff.
<?php

class Elephant
{
    private $_;

    public function __construct(&$_) {
        $this->_ = &$_;
    }

    public function __call($name, array $args) {
        $this->_ = $name(...$args);
        return $this;
    }
};

function ✨(&$_) {
    return new Elephant($_);
}

@hikari-no-yume
Copy link
Author

@sgolemon It could be shorter if I had a method to get the return value. I originally had that in the class when I started writing it, I should maybe add it back.

(The obvious choice of name would be ->_(), but there's a global PHP function called _ already, which is an alias for gettext…)

@hikari-no-yume
Copy link
Author

@Potherca Yep, anonymous classes aren't strictly needed! I originally wrote this as a regular class, but I realised it would be neater and could be used more concisely if I used an anonymous class.

@hikari-no-yume
Copy link
Author

…wait, wouldn't even need a method, if _ was exposed as a public property…

@billschaller
Copy link

What's the perf impact versus nested calls?

@JarJak
Copy link

JarJak commented Mar 22, 2017

<?php declare(strict_types=1);

function ✨($_) {
    return new class($_) {
        public $_;

        public function __construct(&$_) {
            $this->_ = &$_;
        }
        public function __call(string $name, array $args): self {
            $this->_ = $name($this->_, ...$args);
            return $this;
        }
    };
}

$a = 'asd';
echo ✨($a)
    ->md5()
    ->strtoupper()
    ->_;

@mindplay-dk
Copy link

@arzola
Copy link

arzola commented Jun 2, 2017

Awesome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment