php php中的结构数据类型?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3861353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Structs data type in php?
提问by ktm
Can anyone give me example for structs data type in php ? How come there is something like structs in php all of a sudden ?
谁能给我举个 php 结构体数据类型的例子?为什么 php 中突然出现类似结构的东西?
回答by ASpencer
Closest you'd get to a struct is an object with all members public.
最接近结构的是所有成员都是公共的对象。
class MyStruct {
public $foo;
public $bar;
}
$obj = new MyStruct();
$obj->foo = 'Hello';
$obj->bar = 'World';
I'd say looking at the PHP Class Documentationwould be worth it. If you need a one-off struct, use the StdObject as mentioned in alex's answer.
我会说查看PHP 类文档是值得的。如果您需要一次性结构,请使用 alex 的回答中提到的 StdObject。
回答by alex
You can use an array
您可以使用数组
$something = array(
'key' => 'value',
'key2' => 'value2'
);
orwith standard object.
或标准对象。
$something = new StdClass();
$something->key = 'value';
$something->key2 = 'value2';
回答by Ruel
I recommend 2 things. First is associative array.
我推荐两件事。首先是关联数组。
$person = Array();
$person['name'] = "Joe";
$person['age'] = 22;
Second is classes.
二是上课。
Detailed documentation here: http://php.net/manual/en/language.oop5.php
回答by pikuseru
I cobbled together a 'dynamic' struct class today, had a look tonight and someone has written something similar with better handling of constructor parameters, it might be worth a look:
我今天拼凑了一个“动态”结构类,今晚看了一下,有人写了类似的东西,可以更好地处理构造函数参数,可能值得一看:
http://code.activestate.com/recipes/577160-php-struct-port/
http://code.activestate.com/recipes/577160-php-struct-port/
One of the comments on this page mentions an interesting thing in PHP - apparently you're able to cast an array as an object, which lets you refer to array elements using the arrow notation, as you would with a Struct pointer in C. The comment's example was as follows:
该页面上的一条评论提到了 PHP 中的一件有趣的事情——显然您可以将数组转换为对象,这样您就可以使用箭头符号来引用数组元素,就像在 C 中使用 Struct 指针一样。评论的例子如下:
$z = array('foo' => 1, 'bar' => true, 'baz' => array(1,2,3));
//accessing values as properties
$y = (object)$z;
echo $y->foo;
I haven't tried this myself yet, but it may be that you could get the desired notation by just casting - if that's all you're after. These are of course 'dynamic' data structures, just syntactic sugar for accessing key/value pairs in a hash.
我自己还没有尝试过这个,但可能你可以通过强制转换来获得所需的符号 - 如果这就是你所追求的。这些当然是“动态”数据结构,只是用于访问哈希中的键/值对的语法糖。
If you're actually looking for something more statically typed, then ASpencer's answer is the droid you're looking for (as Obi-Wan might say.)
如果您实际上正在寻找更静态类型的东西,那么 ASpencer 的答案就是您正在寻找的机器人(正如 Obi-Wan 可能会说的那样。)
回答by dotancohen
It seems that the struct
datatype is commonly used in SOAP:
似乎该struct
数据类型在 SOAP 中常用:
var_dump($client->__getTypes());
array(52) {
[0] =>
string(43) "struct Bank {\n string Code;\n string Name;\n}"
}
This is not a native PHP datatype!
这不是原生 PHP 数据类型!
It seems that the properties of the struct
type referred to in SOAP can be accessed as a simple PHP stdClass
object:
struct
SOAP 中引用的类型的属性似乎可以作为一个简单的 PHPstdClass
对象访问:
$some_struct = $client->SomeMethod();
echo 'Name: ' . $some_struct->Name;
回答by Timo Huovinen
Only associative arrays are structs in PHP.
PHP 中只有关联数组才是结构体。
And you can't make them strict on their own.
你不能让他们自己严格。
But you can sort of fake structure strictness with classes and interfaces, but beware that unlike structures, class instances are not passed in arguments, their identifiers are!
但是你可以用类和接口来伪造结构严格性,但要注意,与结构不同,类实例不传入参数,它们的标识符是!
You can define a struct through an interface (or at least close to it)
您可以通过接口(或至少接近它)定义结构
Structs enforce a certain structure on an object.
结构在对象上强制执行某种结构。
PHP (<= 7.3) does not have native structs, but you can get around it with interfaces and type hinting:
PHP (<= 7.3) 没有原生结构,但你可以通过接口和类型提示来绕过它:
interface FooStruct
{
public function name() : string;
}
interface BarStruct
{
public function id() : int;
}
interface MyStruct
{
public function foo() : FooStruct;
public function bar() : BarStruct;
}
Any class implementing MyStruct
will be a MyStruct
.
任何实现的类MyStruct
都将是一个MyStruct
.
The way it's build up is not up to the struct, it just ensures that the data returned is correct.
它的构建方式不取决于结构,它只是确保返回的数据是正确的。
What about setting data?
设置数据呢?
Setting struct data is problematic as we end up with getters and setters and it's something that is close to an anemic objector a DTOand is considered an anti-pattern by some people
设置结构体数据是有问题的,因为我们最终得到了 getter 和 setter,它与贫血对象或DTO很接近,并且被某些人认为是反模式
Wrong example:
错误示例:
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;
}
Then we end up with class implementations that might be mutable, and a struct must not mutate, this is to make it a "data type", just like int
, string
.
Yet there's no way to restrict that with interfaces in PHP, meaning people will be able to implement your struct interface in a class that is not a struct.
Make sure to keep the instance immutable
然后我们最终得到可能可变的类实现,并且结构不能改变,这是为了使它成为“数据类型”,就像int
,一样string
。但是没有办法用 PHP 中的接口来限制它,这意味着人们将能够在一个不是结构体的类中实现你的结构体接口。确保实例不可变
Also a struct may then be instantiated without the correct data and trigger errors when trying to access the data.
此外,结构可能会在没有正确数据的情况下被实例化,并在尝试访问数据时触发错误。
An easy and reliable way to set data in a PHP struct class is through its constructor
在 PHP struct 类中设置数据的一种简单可靠的方法是通过其构造函数
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;
}
}
Type hinting using interfaces: (if your IDE supports it)
使用接口类型提示:(如果您的 IDE 支持)
If you don't mind not having the strict type checking, then another way would be using interfaces or classes with comments for the IDE.
如果您不介意不进行严格的类型检查,那么另一种方法是使用带有 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
{
}
The reason to use interfaces instead of classes is for the same reason why interfaces exist in the first place, because then many classes with many implementations can have this same structure and each method/function that uses it will support every class with this interface.
使用接口而不是类的原因与接口首先存在的原因相同,因为许多具有许多实现的类可以具有相同的结构,并且使用它的每个方法/函数都将支持具有此接口的每个类。
This depends on your IDE, so you might need to use classes instead or just live without it.
这取决于您的 IDE,因此您可能需要使用类来代替,或者直接不用它。
Note: Remember that you have to validate/sanitize the data in the instance elsewhere in the code to match the comment.
注意:请记住,您必须验证/清理代码中其他地方的实例中的数据以匹配注释。
回答by David Ryan
A public class is one option, if you want something more encapsulated you can use an abstract/anonymous class combination. My favorite part is that autocomplete still works (for PhpStorm) for this but I don't have a public class sitting around.
公共类是一种选择,如果您想要更封装的东西,您可以使用抽象/匿名类组合。我最喜欢的部分是自动完成仍然有效(对于 PhpStorm),但我没有一个公共课程。
<?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;
}