Quelqu'un peut-il me donner un exemple de type de données structs en php ? Comment se fait-il qu'il y ait soudainement quelque chose comme les structs en php ?
Réponses
Trop de publicités?Il semble que le struct
Le type de données est communément utilisé dans SOAP :
var_dump($client->__getTypes());
array(52) {
[0] =>
string(43) "struct Bank {\n string Code;\n string Name;\n}"
}
Ce n'est pas un type de données natif de PHP !
Il semble que les propriétés de la struct
auquel il est fait référence dans SOAP peut être accédé comme un simple PHP stdClass
objet :
$some_struct = $client->SomeMethod();
echo 'Name: ' . $some_struct->Name;
Seuls les tableaux associatifs sont des structs en PHP.
Et vous ne pouvez pas les rendre strictes par elles-mêmes.
Mais vous pouvez en quelque sorte simuler la rigueur des structures avec des classes et des interfaces, mais attention, contrairement aux structures, les instances de classe ne sont pas passées en arguments, leurs identifiants sont !
Vous pouvez définir une structure par le biais d'une interface (ou du moins s'en approcher)
Les structures imposent une certaine structure à un objet.
PHP (<= 7.3) n'a pas de structs natifs, mais vous pouvez contourner cela avec des interfaces et des indications de type :
interface FooStruct
{
public function name() : string;
}
interface BarStruct
{
public function id() : int;
}
interface MyStruct
{
public function foo() : FooStruct;
public function bar() : BarStruct;
}
Toute classe implémentant MyStruct
será un MyStruct
.
La manière dont il est construit ne dépend pas de la structure, elle garantit simplement que les données renvoyées sont correctes.
Qu'en est-il des données de réglage ?
La définition de données structurées est problématique car nous nous retrouvons avec des getters et setters et c'est quelque chose qui est proche d'un objet anémique ou un DTO et est considéré comme un anti-modèle par certaines personnes
Mauvais exemple :
interface FooStruct
{
public function getName() : string;
public function setName(string $value) : FooStruct;
}
interface BarStruct
{
public function getId() : int;
public function setId(int $value) : BarStruct;
}
interface MyStruct
{
public function getFoo() : FooStruct;
public function setFoo(FooStruct $value) : MyStruct;
public function getBar() : BarStruct;
public function setBar(BarStruct $value) : MyStruct;
}
Ensuite, nous nous retrouvons avec des implémentations de classes qui peuvent être mutables, alors qu'une structure ne doit pas être mutée, ceci pour en faire un "type de données", tout comme int
, string
. Pourtant, il n'y a aucun moyen de restreindre cela avec les interfaces en PHP, ce qui signifie que les gens pourront implémenter votre interface struct dans une classe qui n'est pas une struct. Assurez-vous de garder l'instance immuable
De même, une structure peut être instanciée sans les données correctes et déclencher des erreurs lors de l'accès aux données.
Un moyen simple et fiable de définir des données dans une classe struct PHP est d'utiliser son constructeur.
interface FooStruct
{
public function name() : string;
}
interface BarStruct
{
public function id() : int;
}
interface MyStruct
{
public function foo() : FooStruct;
public function bar() : BarStruct;
}
class Foo implements FooStruct
{
protected $name;
public function __construct(string $name)
{
$this->name = $name;
}
public function name() : string
{
return $this->name;
}
}
class Bar implements BarStruct
{
protected $id;
public function __construct(string $id)
{
$this->id = $id;
}
public function id() : int
{
return $this->id;
}
}
class My implements MyStruct
{
protected $foo, $bar;
public function __construct(FooStruct $foo, BarStruct $bar)
{
$this->foo = $foo;
$this->bar = $bar;
}
public function foo() : FooStruct
{
return $this->foo;
}
public function bar() : BarStruct
{
return $this->bar;
}
}
Indication de type à l'aide d'interfaces : (si votre IDE le supporte)
Si cela ne vous dérange pas de ne pas avoir la vérification stricte des types, une autre solution serait d'utiliser des interfaces ou des classes avec des commentaires pour l'IDE.
/**
* Interface My
* @property Foo $foo
* @property Bar $bar
*/
interface My
{
}
/**
* Interface Foo
* @property string|integer $id
* @property string $name
*/
interface Foo
{
}
/**
* Interface Bar
* @property integer $id
*/
interface Bar
{
}
La raison d'utiliser les interfaces au lieu des classes est la même raison pour laquelle les interfaces existent en premier lieu, parce que de nombreuses classes avec de nombreuses implémentations peuvent avoir cette même structure et chaque méthode/fonction qui l'utilise supportera chaque classe avec cette interface.
Cela dépend de votre IDE, vous devrez peut-être utiliser des classes à la place ou simplement vous en passer.
Note : N'oubliez pas que vous devez valider/sanitiser les données de l'instance ailleurs dans le code pour qu'elles correspondent au commentaire.
Une classe publique est une option, si vous voulez quelque chose de plus encapsulé, vous pouvez utiliser une combinaison de classe abstraite/anonyme. Ce que je préfère, c'est que l'autocomplétion fonctionne toujours (pour PhpStorm) dans ce cas, mais je n'ai pas de classe publique à disposition.
<?php
final class MyParentClass
{
/**
* @return MyStruct[]
*/
public function getData(): array
{
return array(
$this->createMyObject("One", 1.0, new DateTime("now")),
$this->createMyObject("Two", 2.0, new DateTime("tommorow"))
);
}
private function createMyObject(string $description, float $magnitude, DateTime $timeStamp): MyStruct
{
return new class(func_get_args()) extends MyStruct {
protected function __construct(array $args)
{
$this->description = $args[0];
$this->magnitude = $args[1];
$this->timeStamp = $args[2];
}
};
}
}
abstract class MyStruct
{
public string $description;
public float $magnitude;
public DateTime $timeStamp;
}
- Réponses précédentes
- Plus de réponses
14 votes
Où avez-vous lu cette information ? PHP n'a jamais eu de véritable
struct
type de données.0 votes
Veuillez montrer le code ou le lien vers l'endroit où vous avez lu des informations sur les structures en PHP.
5 votes
Il a probablement vu le mot struct quand il a var_dumpé un objet soap.
0 votes
@ktm, faites-vous référence este comme des structs ?
0 votes
@MiloLaMar : C'est aussi là que j'ai entendu parler pour la première fois des structs PHP. De façon frustrante, le
struct
Le terme "class" n'est pas défini dans le document WSDL, ce qui donne l'impression qu'il s'agit d'un type de données PHP natif.1 votes
@ktm Malheureusement, PHP ne supporte pas les structs comme vous les connaissez en C/C++. Vous ne pouvez donc rien faire de tel :
class pseudostruct { (int) myint; (char) mychar; (string) mychar; } myObj = new pseudostruct;
. Ce serait génial si PHP avait cette fonctionnalité car nous pourrions déclarer des structures de données et espérer lire des données et leur assigner des valeurs de manière très simple et efficace, comme en C. Ce serait aussi génial si nous pouvions prédéfinir la taille mémoire exacte des variables ou utiliser malloc. La lecture des données dans les variables de ma classe de pseudo-structure serait alors amusante !