Jump to content

Recommended Posts

Posted (edited)

Viva!

É verdade que não pesquisei muito sobre o assunto na esperança de obter aqui na comunidade o que procuro 🙂

Existe alguma forma mais recente de "forçar" o tipo (class) de elemento de uma lista? Também com o propósito de aquando a programar com o IDE, obtenhamos com o type hint a indicação da classe do elemento.

Exemplo:


class Tipo {

}

class Teste {

/**
 * Aqui quero uma lista de objetos da classe Tipo
 */
private $lista1 = array();

/**
 * Aqui quero uma lista de strings
 */
private $lista2 = array();

// Construtor bla bla bla...

/**
 * Magic get para obter a propriedade
 */
public function __get($prop) {
	return $this->$prop;
}
}

// Depois fora da classe, ao programar, queria saber qual o tipo de elemento da lista, assim:
$teste = new Teste();
$item = reset($teste->lista1); // aqui queria saber qual o tipo (ou classe) do elemento

// O mesmo para adicionar...
$teste = new Teste();
$teste->lista1[] = '' // Só deveria deixar adicionar elementos de um determinado tipo... (isto sem ser necessário criar um método específico para adicionar elementos).

Sei que em Java podem-se definir o tipo dos elementos de uma lista com List<String> stringList = new ArrayList<String>();

Existe em PHP algo recente que também permita definir assim um array?

Obrigado.

Edited by taviroquai
Posted (edited)

os arrays em php sempre foram intrinsecamente heterogéneos.

por outras palavras : nop.

o que deverias ter para forcar isso seria (em PHP 5):

class Tipo {
 public $i;

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

class ArrayTipo extends ArrayObject
{
 public function __construct()
 {
   // prevent all the strange initialization process of the base class
   parent::__construct();
 }

 public function append($value)
 {
   if (!($value instanceof Tipo))
   {
     throw new Exception("invalid input");
   }
   parent::append($value);
 }

 public function offsetSet($index, $newval)
 {
   if (!($newval instanceof Tipo))
   {
     throw new Exception("invalid input");
   }
   parent::offsetSet($index, $newval);
 }

 public function exchangeArray($input)
 {
   if (!is_array($input))
   {
     return false;
   }

   foreach ($input as $value)
   {
     if (!($value instanceof Tipo))
     {
       return false;
     }
   }

   parent::exchangeArray($input);
 }
}

$lista = new ArrayTipo();
Edited by HappyHippyHippo
IRC : sim, é algo que ainda existe >> #p@p
Posted

Ya happy com isso garanto que só adiciono itens do tipo Tipo... e com isto garantia o type hint ao devolver:

/**
* @return Tipo
*/
public function getItemLista1($offset) {
   return $this->lista1[$offset];
}

@yoda, sim... dessa forma posso forçar a inserção de elementos só dessa class...

Mas lá está... teria que criar métodos específicos para cada lista... Pois se não houver outra forma tenho que criar estes 2 métodos... o método para inserir e o método para obter o item...

Posted (edited)
<?php
/**
* @author Pedro Gouveia Sousa
*/
class Tipo {
private $id;

function __construct($id) {
 $this->id = $id;
}

public function getId() {
 return $this->id;
}
}
class TipoA extends Tipo {

function __construct($id) {
 parent::__construct($id);
}
}
class TipoB extends Tipo {
function __construct($id) {
 parent::__construct($id);
}
}
class Teste {
private $nome = "Class Test";

public function getNome() {
 return $this->nome;
}
private $lista = [];

public function getLista() {
 return $this->lista;
}

public function addTipo (Tipo $novoTipo) { // só objectos da class TIPO
 $this->lista[] = $novoTipo;
}

public function getObjecto ($elemento) {
 return $this->lista[$elemento];
}

public function getClass($elemento) {
 return get_class($elemento);
}
}
$teste = new Teste("IDTeste");
$umTipo = new TipoA("IDTipoA");
$outroTipo = new TipoB("IDTipoB");
$aindaOutroTipo = new Tipo("Sou 'parent' mas sou um tipo tambem..");
if ($teste->getClass($umTipo) == 'TipoA') // aqui escolhes a classe..se é da class X adiciona.
$teste->addTipo($umTipo);
$teste->addTipo($outroTipo); // aqui não há nenhuma condicao, 'entra' tudo...
$teste->addTipo($aindaOutroTipo);
foreach($teste->getLista() as $objecto) {
echo "Sou do {$teste->getClass($objecto)}";
echo " e tenho o ID: " . $objecto->getId() . "<br>";
}
echo '<pre>';
print_r($teste->getLista());

Pelo que percebi é isso que queres... =)

Edited by PeterS
Posted (edited)

Não sei qual o IDE que usas mas para o netbeans para forçar a aparecer os métodos da class faço assim.

Por exemplo para usar os métodos da class PDO:

/*** @var PDO $conn */

public static $conn = NULL;

O IDE sabe que a variável $conn pertence à class PDO e sempre que usares $conn->, o IDE dá-te os métodos do PDO.

Também podes fazer com a variável teste acima descrito ....

ATENÇÃO: Funciona no Netbeans à buereré, agora nos outros desconheço...

Edited by PeterS
Posted

E então não pode porque?

No array em cima, o array tem tipo bem definidos..... TipoA, TipoB, etc..., e é aceite porque TipoA é de determinado Tipo.

Até podes criar a class String, boolean etc... e usar o type hint na chamada do parametro da funcão como está em cima...

Posted

1º - o que tens não é um array, é uma classe.

2º - lê bem o que OP escreveu:

Existe em PHP algo recente que também permita definir assim um array?

ele pediu um array, é porque necessita de uma array. e como disse a tua solução não é um array é uma classe convencional !!!

se te desses ao trabalho de ler tanto o código que apresentei assim com ler o código de exemplo :

$lista[] = 34;         /* erro : tipo de dados não aceite */
$lista[] = 'sf';       /* erro : tipo de dados não aceite  */
$lista[] = true;       /* erro : tipo de dados não aceite  */
$lista[] = new Tipo(); /* ok */

verias que o que está a ser criado é uma classe (não existe outra forma, sem usar classes), mas com o interface de um array que só aceita o tipo de dados pedido pelo OP.

IRC : sim, é algo que ainda existe >> #p@p
Posted

Estamos todos aqui para aprender, mesmo com alguns anos nisto, pelo menos eu.

Eu li mais de 40 vezes tudo o que foi aqui falado, não há necessidade de falares assim, aliás eu meti até mais código que tu e tive a amabilidade de andar a me preocupar com o problema dele e até sou novo aqui no fórum.

Em PHP, um array pode ter TODOS os tipos que quisermos, e no problema que ele falou, ele pode verificar qualquer que seja o tipo de dados existente no array!

No problema do jovem que abriu o topico e ainda não falou, o indexed array pode estar assim:

lista[0] = 10;
lista[1] = "10";
lista[2] = true;
lista[3] = "TipoA object";
lista[4] = "TipoB object";
lista[5] = "Seja o que for object";

Neste caso, é tirar o (Tipo $umTipo) na classe teste, e fica ($umTIpo), e podemos testar se é string, numero, boolean, array, objecto do TipoA, TipoB, e ele pode testar qual é o tipo de elemento que está no array e depois fazer o que quiser...

$lista[] = 34;		 /* ok */
$lista[] = 'sf';	 /* ok */
$lista[] = true;	 /* ok */
$lista[] = new Tipo(); /* ok */
$lista[] = new sadfdsfjdslfsdjlfdslj(); /* ok */

Para o problema que o jovem falou(ele comentou o código), é isso que ele quer...um array não tem que ter só inteiros ou strings associadas, pode ter qualquer tipo.

Posted

Sim pode, neste caso:

public function addTipo (Tipo $novoTipo) { // só objectos da class TIPO

$this->lista[] = $novoTipo;

}

Força a que o elemento seja do Tipo "Tipo". TipoA e TipoB são subclasses de Tipo.

Posted

Não devo estar a perceber, peço desculpa se estou a ser chato.

Então entrava como parametro em vez do objecto da class Tipo, o parametro era um array e nesse array tinha elementos de vários tipos?

E depois ele testava os tipos desses elementos?

Posted

Porque não dizes tudo de uma vez ?

Um array é um conjunto de elementos, por exemplo, no mundo real, o array mochila pode ter livros, canetas, etc.

Interagir com um array posso interagir de várias formas....(foreach, each, while, for)

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.