在以下代码中:
$storage = new \SplObjectStorage();
$fooA = new \StdClass();
$fooB = new \StdClass();
$storage[$fooA] = 1;
$storage[$fooB] = array();
$storage[$fooA] = 2;
$storage[$fooB][] = 'test';
Run Code Online (Sandbox Code Playgroud)
我希望$storage[$fooA]是1,它是.我也希望$storage[$fooB]如此array('test'),但事实并非如此.这也会触发一条通知,内容为"间接修改SplObjectStorage的重载元素对...没有影响"
我认为这是因为ArrayAccessin 的实现SplObjectStorage不通过引用返回值.
有没有办法SplObjectStorage用作数据映射,其中键是对象,值是可变数组?做这种工作还有其他可行的选择吗?
array_values()不适用于ArrayAccess对象。也不array_keys()
为什么?
如果我可以访问,$object['key']我应该能够执行所有类型的数组操作
我有一个对象集合,表现得像一个数组.它是一个数据库结果对象.类似于以下内容:
$users = User::get();
foreach ($users as $user)
echo $user->name . "\n";
Run Code Online (Sandbox Code Playgroud)
该$users变量是一个实现对象ArrayAccess和Countable接口.
我想对这个"数组"进行排序和过滤,但我不能在其上使用数组函数:
$users = User::get();
$users = array_filter($users, function($user) {return $user->source == "Twitter";});
=> Warning: array_filter() expects parameter 1 to be array, object given
Run Code Online (Sandbox Code Playgroud)
如何我可以排序和筛选这种类型的对象?
尝试更新到 php 8.1 并注意到这个已弃用的通知出现在我想要处理的错误日志中。
[14-Feb-2022 14:48:25 UTC] PHP Deprecated: Return type of TLDExtractResult::offsetExists($offset) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/example/public_html/assets/tldextract/tldextract.php on line 299
我能够抑制警告,但实际上想更新脚本,这样将来就不会出现问题。
//public function offsetExists($offset) {
// return array_key_exists($offset, $this->fields);
//}
#[\ReturnTypeWillChange]
public function offsetExists(mixed $offset) {
return array_key_exists($offset, $this->fields);
}
Run Code Online (Sandbox Code Playgroud)
这是有问题的代码部分:
class TLDExtractResult implements ArrayAccess {
private $fields;
public function __construct($subdomain, $domain, $tld) {
$this->fields = array(
'subdomain' => $subdomain,
'domain' => …Run Code Online (Sandbox Code Playgroud) 编辑:我意识到文本量可能令人生畏。这个问题的本质是:
如何以能够设置多维值的方式实现ArrayAccess?
我知道这已经在这里讨论过,但我似乎无法正确实现 ArrayAccess 接口。
基本上,我有一个类来处理带有数组和实现的应用程序配置ArrayAccess。检索值工作正常,甚至是来自嵌套键 ( ) 的值$port = $config['app']['port'];。不过,设置值仅适用于一维数组:一旦我尝试设置(取消)设置一个值(例如上一个示例中的端口),我就会收到以下错误消息:
Notice: Indirect modification of overloaded element <object name> has no effect in <file> on <line>
Run Code Online (Sandbox Code Playgroud)
现在普遍的观点似乎是该offsetGet()方法必须通过引用返回(&offsetGet())。然而,这并不能解决问题,而且我担心我不知道如何正确实现该方法 - 为什么使用 getter 方法来设置值?这里的php 文档也没有太大帮助。
要直接复制此内容(PHP 5.4-5.6),请查找下面附加的示例代码:
<?php
class Config implements \ArrayAccess
{
private $data = array();
public function __construct($data)
{
$this->data = $data;
}
/**
* ArrayAccess Interface
*
*/
public function offsetSet($offset, $value)
{
if (is_null($offset)) {
$this->data[] …Run Code Online (Sandbox Code Playgroud) 为什么这段代码不产生相同的程序集?(g++ -O3) 我对汇编知之甚少,但似乎情况 2 访问的指令较少,所以应该首选,对吗?我问这个是因为我想用返回一个指针的访问运算符来实现一个包装类int* p = a[i](所以访问是a[i][j],而不是a[i*3+j]),但不知道它是否值得。感谢您的任何帮助。
#include <iostream>
int main() {
int a[9];
int i, j, k;
// Case 1
std::cin >> i >> j >> k;
*(a + i*3 + j) = k;
std::cin >> i >> j >> k;
(&a[i*3])[j] = k;
std::cin >> i >> j >> k;
*((&a[i*3])+j) = k;
// Case 2
std::cin >> i >> j >> k;
a[i*3 + j] = k;
std::cout << a[0]; …Run Code Online (Sandbox Code Playgroud) 我试图理解ArrayAccess接口背后的想法,
我不明白每个方法的含义,如果那些方法(函数)是"内置"函数而ArrayAccess接口(也是"内置")只是"确保"我将实现那些"内置"方法(函数) )
我试图理解每个函数在我们的代码"幕后花絮"中做了什么.
function offsetSet($offset, $value);
function offsetGet($offset);
function offsetUnset($offset);
function offsetExists($offset);
Run Code Online (Sandbox Code Playgroud)
如果我理解ArrayAccess是一个内置接口,包含要实现的密封,当我们实现它们时,我们只实现对内置函数的引用,如果有人能帮助我做到这一点,我将很高兴.
为什么我们使用ArrayAccess::offsetUnset()代替我希望unset()足以使用。但是 php.net 指出:
注意:当类型转换为 (unset) 时不会调用此方法
谁能告诉我们如何使用它,它是否会自动从实现ArrayAccess接口的类中取消设置被调用的偏移元素?
参考链接http://php.net/manual/en/arrayaccess.offsetunset.php。
谢谢 !!!
arrayaccess ×8
php ×7
arrays ×3
spl ×3
assembly ×1
c++ ×1
c++20 ×1
countable ×1
deprecated ×1
php-8.1 ×1