我正在用PHP建立一个应用程序,试图遵循Laravel中规定的一些约定,我看到有很多对$this->app["some_var"];
的引用
但是在我的应用程序中,它抛出一个错误,提示“不能将对象用作数组”。
我知道Laravel使用了__get()
和__set()
之类的魔术方法
包括在内,但是仍然得到相同的结果。
我在App对象的父类中使用的神奇的getter和setter代码
/**
* Dynamically access container services.
*
* @param string $key
* @return mixed
*/
public function __get($key)
{
return $this[$key];
}
/**
* Dynamically set container services.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function __set($key, $value)
{
$this[$key] = $value;
}
期望的结果是它可以访问该对象上不可访问的任何属性吗?
当前抛出一个Fatal error: Uncaught Error: Cannot use object Application as type of array.
答案 0 :(得分:1)
您需要实现ArrayAccess 请参见https://www.php.net/manual/en/class.arrayaccess.php中的以下代码 以下代码将数组值存储在$ container数组中,并将$ obj ['key']代理到该数组对象
<?php
class obj implements ArrayAccess {
private $container = array();
public function __construct() {
$this->container = array(
"one" => 1,
"two" => 2,
"three" => 3,
);
}
public function offsetSet($offset, $value) {
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
public function offsetExists($offset) {
return isset($this->container[$offset]);
}
public function offsetUnset($offset) {
unset($this->container[$offset]);
}
public function offsetGet($offset) {
return isset($this->container[$offset]) ? $this->container[$offset] : null;
}
}
$obj = new obj;
var_dump(isset($obj["two"]));
var_dump($obj["two"]);
unset($obj["two"]);
var_dump(isset($obj["two"]));
$obj["two"] = "A value";
var_dump($obj["two"]);
$obj[] = 'Append 1';
$obj[] = 'Append 2';
$obj[] = 'Append 3';
print_r($obj);
?>
答案 1 :(得分:1)
Laravel内核的Application类扩展了一个实现ArrayAccess的Container类。
构建ArrayAccess接口的方法有多种,Laravel使用了一种复杂的方法,因为它比defualt方法要满足更多的要求,但是总之,您需要为offsetExists(),offsetGet(), offsetSet()和offsetUnset()方法,然后可以使用ArrayAccess语法。
默认情况下,在供应商上,您可以在下一个路径:Illuminate\Container\Container
中看到ArrayAccess在ArrayAccess中的扩展用法,并且有实现该方法的代码:
/**
* Determine if a given offset exists.
*
* @param string $key
* @return bool
*/
public function offsetExists($key)
{
return isset($this->bindings[$key]);
}
/**
* Get the value at a given offset.
*
* @param string $key
* @return mixed
*/
public function offsetGet($key)
{
return $this->make($key);
}
/**
* Set the value at a given offset.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function offsetSet($key, $value)
{
// If the value is not a Closure, we will make it one. This simply gives
// more "drop-in" replacement functionality for the Pimple which this
// container's simplest functions are base modeled and built after.
if (! $value instanceof Closure) {
$value = function () use ($value) {
return $value;
};
}
$this->bind($key, $value);
}
/**
* Unset the value at a given offset.
*
* @param string $key
* @return void
*/
public function offsetUnset($key)
{
unset($this->bindings[$key], $this->instances[$key], $this->resolved[$key]);
}
理解ArrayAccess的最简单方法就像Somesh Mukherjee的答案所解释的。
答案 2 :(得分:0)
Array和Object是PHP中的两种不同的数据类型。要访问数组变量,我们需要使用方括号 [] 。 例如,
$a = array('one','two','three');
$a[] = "four";
echo $a[3]; //Output: four.
但是,用于访问对象变量
$a = new {className}();
$a->key = 'value'; //Using magic method __get()
echo $a->key; //Output: value
在类方面, $ this 指的是该特定类的对象。因此,您不能使用 [] 方括号来分配变量。为此,您需要使用-> 箭头。
内部类中,您需要按如下方式重写函数
public function __get($key) {
return $this->$key ?: false;
}
public function __set($key,$value) {
$this->$key = $value;
}
否则,您可以在类内创建一个新的数组变量,如下所示:
class className {
public $a = array();
public function __get($key) {
return $this->a[$key] ?: false;
}
public function __set($key,$value) {
return $this->a[$key] = $value;
}
}