Induction type for any type of object

4

I want to make a method of a given class accept an object as a parameter. But this object could be of any type. Example:

class classeExemplo
{
    public function meuMetodo(Object $objeto)
    {
        // Seguiria aqui o bloco de código
    }
}

// Instanciando meus objetos
$produto = new Produto();
$usuario = new Usuario();

/* alimentaria meus objetos com suas respectivas informações */

// Instaciando minha classe que tem o método que recebe qualquer tipo de Objeto
$exemplo = new classeExemplo();

// Chamando o método passando objetos diferentes
$exemplo->meuMetodo($produto);
$exemplo->meuMetodo($usuario);

This obviously does not work. Has anyone ever been in a similar situation? How could you get around and somehow make it work?

    
asked by anonymous 24.11.2015 / 20:59

5 answers

3

PHP is a dynamic language. The normal thing is to accept any type, so just do not specify any type that will be accepted:

class Produto{}
class Usuario {}
class classeExemplo
{
    public function meuMetodo($objeto) //<======== mudei aqui
    {
        // Seguiria aqui o bloco de código
    }
}

// Instanciando meus objetos
$produto = new Produto();
$usuario = new Usuario();

/* alimentaria meus objetos com suas respectivas informações */

// Instaciando minha classe que tem o método que recebe qualquer tipo de Objeto
$exemplo = new classeExemplo();

// Chamando o método passando objetos diferentes
$exemplo->meuMetodo($produto);
$exemplo->meuMetodo($usuario);

See running on ideone .

    
24.11.2015 / 21:19
2

Although what you're trying does not make sense (in any language), below is the closest you can get:

class classeExemplo
{
    public function meuMetodo($objeto)
    {
        if (!is_object($objeto)) {
            throw new InvalidArgumentException("Not an object!");            
        }

        print "ok\n";
    }
}
    
24.11.2015 / 22:20
1

Currently it is not possible to define types, because PHP usually accepts any type, but adding the prefix Object to the argument, you are not properly declaring the type for this argument, you are declaring the instance to which that object must belong.

<?php
class Teste
{
    public function show(Object $arg)
    {   
        return $arg;
    }
}
class Object {}
$objecto = (object) 'Teste';
// $objecto = new stdClass();

$teste = new Teste();
var_dump($teste->show(new Object)); # funciona (instancia de Object)
var_dump($teste->show($objecto)); # não funciona (instancia de stdClass)

?>

To solve this, just do not assign a prefix to the argument in question, and everything will work fine.

<?php
...
public function show($arg)
        {   
            return $arg;
        }
...
?>

But if you really want to define a specific type for that argument, or a requirement for that particular argument, then you must work on that argument to create that rule.

Another example would be this:

<?php

class Teste
{
    public function show($object=null)
    {
        if(!empty($object) && gettype($object) === 'object'){
            if(!($object instanceof stdClass)){
                return  "Retorno: \"{$object}\" é um objecto <br/>";
            }
            throw new Exception('é um objecto, mas não pode ser retornado como string');
        }
        throw new Exception("\"{$object}\" é " . gettype($object));
    }
}
class Object
{
    protected $nome;
    public function __construct($nome=null){
        $this->nome = $nome;
    }
    public function __toString(){
        if(!empty($this->nome)){
            return $this->nome;
        }
        return 'default';
    }
}

$teste = new Teste();
try{
    // print $teste->show(new stdClass());
    print $teste->show(new Object('LMAO'));
    // print $teste->show(new Object());
    // print $teste->show(1);
    // print $teste->show('teste');
    // print $teste->show(0.01);
} catch (Exception $e){
    print 'Excepção: ' . $e->getMessage();
}

?>

It simply throws an exception if the instance is not an object, or if it is an instance of stdClass .

You can now pass arguments by reference, and also specify return types for functions, if you want to know more, you can follow this link and browse the "Funcions" and "Classes and Objects" categories . Of course, if you look even more, you can still find other good suggestions, there is no shortage.

    
25.11.2015 / 06:55
0

In addition to the methods presented in the other answers, you can create a class encompassing the others you want to pass in this parameter:

Code:

abstract class FooBar {
   public $name;
}

class Foo extends FooBar {
   public $name = "Foo";
}

class Bar extends FooBar {
   public $name = "Bar";
}

class Outra{
   public $name = "Outra";
}

class Teste {
   public function testar(FooBar $obj){
      echo $obj->name;
   }
}


$teste = new Teste();

$foo = new Foo();
$bar = new Bar();

$out = new Outra();

$teste->testar($foo);
echo PHP_EOL;
$teste->testar($bar);
echo PHP_EOL;
$teste->testar($out);

Output:

Foo
Bar
<br />
<b>Catchable fatal error</b>:  Argument 1 passed to Teste::testar() must be an instance of FooBar, instance of Outra given, called in [...][...] on line 37 and defined in <b>[...][...]</b> on line <b>20</b><br />
    
25.11.2015 / 15:37
0

This technique you refer to is called overloading . This concept does not exist in PHP. If you try to define two methods with the same name but with different arguments, you will get a syntax error.

What you can do is the following:

public function meuMetodo($argumento)
{
    if ($argumento instanceof Produto) {
        // ...
    }
    elseif ($argumento instanceof Usuario) {
        // ...
    }
    else {
        throw new \Exception('Tipo de argumento inválido.');
    }
}

You can also use a block switch :

public function meuMetodo($object argumento)
{
    switch(get_class($argumento)) {
        case 'Produto':
            // ...
            break;
        case 'Usuario':
            // ...
            break;
        default:
            throw new \Exception('Tipo de argumento inválido.');
}
    
25.11.2015 / 17:01