PHP Freakshow

Leonardo Tumadjian


PHP Experience 2016

Antes de começarmos:

Contribua com sua comunidade mais próxima, se tiver um tempo ;)


Como contribuir?

Atenção!

O conteúdo a seguir pode conter cenas fortes, códigos sujos, violência contra as boas práticas, esquisitices, loucuras e muito mais..

Em caso de fortes problemas cardíacos prefira: Design Patterns, SOLID, DDD e etc.. Não tente fazer isso em casa, e muito menos no trabalho, obrigado!

Wellcome!

Sejam bem vindos ao PHP Freak Show, o show já vai começar, preparem-se.

Variáveis variáveis!


$freak = 'ola';
$ola = 'como';
$como = 'vai';
$vai = 'voce';
$voce = 'cara';
$cara = 'zoeira';
$zoeira = 'never ends!';

echo $$$$$$$freak; // Imprime: never ends!?

// ... class Robot
private $precious1 = 'Nooo 1';
protected $precious2 = 'Nooo 2';

public function __get($prop)
{
    return $this->$prop; // <- Explodindo o encapsulamento!
}
// ...
$robot = new Robot();
echo $robot->precious1; // Nooo 1
echo $robot->precious2; // Nooo 2

Agora a aberração:

Ainda mais...

// ...
$obj = 'myRobot';
$class = 'Robot';
$param1 = 'Robotron';
$param2 = 5532;       
$method = 'say';
$word = 'Hello Humans';

$$obj = (new $class($param1, $param2))->$method($word); // Imprime Hello Humans
// ...

Standard PHP Library

Usaremos:

  1. ArrayIterator
  2. ArrayAccess(Interface)

Primeira Loucura


class Writer extends \ArrayIterator
{
    public function offsetGet($index) 
    {
        echo $index . ' ';
        return $this;
    }
}

$whiter = new Writer();
$whiter['Hello']['World']; // Imprime: Hello World

$whiter['But']['when']['this']['is']['over?']; // Imprime: But when this is over? 

Sempre pode piorar!

Posso?


class Crazy implements \ArrayAccess 
{
    // ... some code here
    public function offsetGet($offset) 
    {
        $this->phrase[] = $this->tagIn() . $offset . $this->tagOut();
        return $this;
    }
    // ...
    public function color($colorHex)
    {
        $last = &$this->phrase[count($this->phrase)-1];
        $last = '
' . $last . '
'; return $this; } // ... more code bellow }

Agora vamos usa-la?

E agora? Onde está seu deus?


// Using the class Crazy! Roda no PHP 7!
(new Crazy)
    ['só da']->color('brown')
    ['loco']
    ['aqui']->color('red')
    ['olha o que']
    ['esse barba']
    ['esta']->color('blue')
    ['fazendo']
    ['que']->color('red')
    ['maluco']
    ['das']->color('green')
    ['ideias']
->write();

Variadics

PHP 5.6+


$class = 'Robot';
$method = 'talk';
$arr = ['hello', 'world'];

// Old but GOLD
call_user_func_array([new $class, $method], $arr);


// OR WARNING PHP 5.6+
$robot = (new $class)->$method(...$arr);

Métodos Mágicos

O mago

Aos Javeiros!

Usando o método __call


class DataMaker
{
    protected $matrix;
    // ...
    public function __call($name, $args) 
    {
        $this->matrix[$name] = $args[0];
        return $this;
    }
    // ...
}


$dados = (new DataMaker)
        ->nome('Leonardo')
        ->telefone('11 95555-2233')
        ->endereco('Rua Teste 123')
        ->teste('colocando char especial')
        ->toClass('Customer');
        
var_dump($dados);

Retorno:


object(Customer)[2]
  public 'nome' => string 'Leonardo' (length=8)
  public 'telefone' => string '11 97379-7752' (length=13)
  public 'endereco' => string 'Rua Teste 123' (length=13)
  public 'teste' => string 'colocando char especial' (length=23)

Algumas ideias usando um Router:


// A crazy Router interface
(new GET)['/ola']
        ->controller('Carro')
        ->action('hello');
        
// A Fluid Interface Programming
request('POST')
    ->to('/cliente')
    ->controller('Carro')
    ->action('hello');

// Pratical Router
$post = new Post;

$post['/hello'] = function ($name) {
    return 'Hello ' . $name;
};

Bom acho que acabamos..


// freak instanciator
function __($class, array $parms=[]) {
    return new $class(...$parms);
}
__('FreakPower')
    [function () {
        echo '1';
    }][function () {
        echo '2';
    }][function () {
        echo '3';
    }][function () {
        echo '4';
    }][function () {
        echo '5';
    }]
->fire(); // Dispara as closures aleatoriamente, Imprime, ex: 43152


Hey! espera! não, não faça isso!

Utilidade pública..

Owesome solution by Ocramius


$reader = function & ($object, $property) {
    $value = & Closure::bind(function & () use ($property) {
        return $this->$property;
    }, $object, $object)->__invoke();

    return $value;
};

$kitchen = new Kitchen();
$cake    = & $reader($kitchen, 'cake'); // $this->cake is private
$cake    = 'sorry, I ate it!';

var_dump($kitchen);

Reference: Accessing private PHP class members without reflection

Espero que tenham gostado

“Yolo lo!” ―Mago do Age of Empires


use function yolo\y;

yolo\yolisp(y('yolo\yolo',
    y('lambda', y('request'), 
        y('new', YoLo\resPONsE::clASS, y('quote', "yolo \u{1f640}"))
    )
));

https://yolophp.computer/
https://github.com/igorw/yolo

Obrigado!

https://joind.in/talk/328b5

Slides e exemplos em:

https://github.com/leoqbc/php-freakshow2