Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

@sgolemon 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

This comment has been minimized.

Copy link

@anovsiradj anovsiradj commented Mar 21, 2017

Awesome!

@Potherca

This comment has been minimized.

Copy link

@Potherca Potherca commented Mar 21, 2017

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

This comment has been minimized.

Copy link
Owner Author

@hikari-no-yume hikari-no-yume commented Mar 21, 2017

@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

This comment has been minimized.

Copy link
Owner Author

@hikari-no-yume hikari-no-yume commented Mar 21, 2017

@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

This comment has been minimized.

Copy link
Owner Author

@hikari-no-yume hikari-no-yume commented Mar 21, 2017

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

@billschaller

This comment has been minimized.

Copy link

@billschaller billschaller commented Mar 21, 2017

What's the perf impact versus nested calls?

@JarJak

This comment has been minimized.

Copy link

@JarJak 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

This comment has been minimized.

Copy link

@mindplay-dk mindplay-dk commented Mar 24, 2017

@arzola

This comment has been minimized.

Copy link

@arzola arzola commented Jun 2, 2017

Awesome

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