任何人都可以给我php中的结构数据类型的例子吗?为什么突然间会出现类似于结构的结构?
答案 0 :(得分:88)
最接近结构是一个公共所有成员的对象。
class MyStruct {
public $foo;
public $bar;
}
$obj = new MyStruct();
$obj->foo = 'Hello';
$obj->bar = 'World';
我会说看PHP Class Documentation是值得的。 如果您需要一次性结构use the StdObject as mentioned in alex's answer。
答案 1 :(得分:43)
您可以使用数组
$something = array(
'key' => 'value',
'key2' => 'value2'
);
带有标准对象的或。
$something = new StdClass();
$something->key = 'value';
$something->key2 = 'value2';
答案 2 :(得分:2)
我今天拼凑了一个'动态'结构类,今晚看了一下,有人写了类似的东西,更好地处理构造函数参数,可能值得一看:
http://code.activestate.com/recipes/577160-php-struct-port/
本页面上的一条评论提到了PHP中一件有趣的事情 - 显然你可以将一个数组转换为一个对象,这可以让你使用箭头符号引用数组元素,就像使用一个Struct指针一样C.评论的例子如下:
$z = array('foo' => 1, 'bar' => true, 'baz' => array(1,2,3));
//accessing values as properties
$y = (object)$z;
echo $y->foo;
我自己还没有尝试过这个,但可能是你可以通过演员获得所需的乐谱 - 如果这就是你所追求的全部。这些当然是“动态”数据结构,只是用于访问散列中的键/值对的语法糖。
如果你真的想找一些更静态输入的东西,那么ASpencer的答案就是你正在寻找的机器人(正如欧比万所说的那样)。
答案 3 :(得分:2)
似乎struct
数据类型在SOAP 中常用:
var_dump($client->__getTypes());
array(52) {
[0] =>
string(43) "struct Bank {\n string Code;\n string Name;\n}"
}
这不是本机PHP数据类型!
似乎SOAP中引用的struct
类型的属性可以作为简单的PHP stdClass
对象访问:
$some_struct = $client->SomeMethod();
echo 'Name: ' . $some_struct->Name;
答案 4 :(得分:1)
我推荐两件事。首先是关联数组。
$person = Array();
$person['name'] = "Joe";
$person['age'] = 22;
其次是类。
答案 5 :(得分:0)
您不能对它们进行严格限制。
但是您可以使用类和接口对结构进行严格的伪造,但要注意,class instances are not passed in arguments, their identifiers are与结构不同!
结构在对象上强制执行某种结构。
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;
}
任何实现MyStruct
的类都将是MyStruct
。
其构建方式不取决于结构,它只是确保返回的数据正确。
设置结构数据是有问题的,因为我们最终会遇到getter和setter,而且它接近anemic object或DTO且considered an anti-pattern by some people
错误的示例:
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;
}
然后,我们最终得到的类实现可能是可变的,并且结构不得突变,这是使其成为“数据类型”,就像int
,string
一样。
但是,没有办法用PHP中的接口来限制它,这意味着人们将能够在不是结构的类中实现您的结构接口。
确保保留实例immutable
然后在没有正确数据的情况下实例化结构,并在尝试访问数据时触发错误。
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;
}
}
如果您不介意不进行严格的类型检查,那么另一种方法是使用带有注释的接口或类作为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
{
}
使用接口而不是类的原因与最初存在接口的原因相同,因为那时具有许多实现的许多类可以具有相同的结构,并且使用该接口的每个方法/函数都将为此支持每个类界面。
这取决于您的IDE,因此您可能需要改用类,或者只是不使用它而生活。
注意: 请记住,您必须在代码中其他地方验证/清除实例中的数据以匹配注释。
答案 6 :(得分:0)
公共类是一个选择,如果您想封装更多内容,可以使用抽象/匿名类组合。我最喜欢的部分是,自动完成仍然可以(对于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;
}