php array of objects
Класс ArrayObject
Введение
Данный класс позволяет объектам работать как массивы.
Обзор классов
Предопределённые константы
Опции ArrayObject
Свойства объекта получают стандартное поведение при доступе в виде списка (var_dump, foreach и т.д.).
ArrayObject::ARRAY_AS_PROPS
Записи могут быть доступны как свойства (для чтения и записи).
Содержание
User Contributed Notes 21 notes
As you know ArrayObject is not an array so you can’t use the built in array functions. Here’s a trick around that:
Extend the ArrayObject class with your own and implement this magic method:
Note: You might want to write your own functions if you’re working with large sets of data.
There is a better explanation about the ArrayObject flags (STD_PROP_LIST and ARRAY_AS_PROPS) right here:
I found the description of STD_PROP_LIST a bit vague, so I put together a simple demonstration to show its behavior:
ArrayObject Object
(
[storage:ArrayObject:private] => Array
(
[prop] => prop data
[arr] => array data
)
$company = new RecursiveArrayObject(array(
‘ceo’ => array(
‘id’ => 1,
‘name’ => ‘tony’,
‘age’ => 36
),
‘coo’ => array(
‘id’ => 2,
‘name’ => ‘matt’,
‘age’ => 35
),
‘cto’ => array(
‘id’ => 3,
‘name’ => ‘james’,
‘age’ => 35
)
));
var_dump($company->cto->name); // string(5) «james»
var_dump($company[‘coo’][‘name’]); // string(4) «matt»
I don’t believe the same performance is true since PHP 5.3. Using the same fill, read_key and foreach approach on both native arrays and ArrayObjects with 10000 keys I get the following
array() fill 0.013101
array() read 0.008685
array() foreach 0.004319
ArrayObject fill 0.014136
ArrayObject read 0.010003
ArrayObject foreach 3.454612
array() fill 0.010395
array() read 0.005933
array() foreach 0.001903
ArrayObject fill 0.010598
ArrayObject read 0.006387
ArrayObject foreach 0.003451
This was the code I used for both, an array or ArrayObject is passed into each of the functions. Again PEAR::Benchmark was used to get the results.
If you want numerical ArrayObject objects to play nice with json_encode(), implement JsonSerializable:
For assoc ArrayObject objects this isn’t neccesary, but for numerical arrays it is, otherwise they will be formatted like
If you plan to derive your own class from ArrayObject, and wish to maintain complete ArrayObject functionality (such as being able to cast to an array), it is necessary to use ArrayObject’s own private property «storage».
Since that is impossible to do directly, you must use ArrayObject’s offset
As a side benefit, this means you inherit all the iteration and other functions in complete working order.
This may sound obvious to someone who has never implemented their own ArrayObject class. but it is far from so.
offsetSet(name,bob)
offsetSet(friend,jane)
Array
(
[name] => bob
[friend] => jane
) */
?>
If you wish to use the «Array as Properties» flag, you simply need to include this in your constructor:
I’ve got an array of cats objects:
and I want to extract an array of cats’ IDs in 1 line (not a function nor a loop).
I was thinking about using array_walk with create_function but I don’t know how to do it.
10 Answers 10
If you have PHP 5.5 or later, the best way is to use the built in function array_column() :
But the son has to be an array or converted to an array
Warning create_function() has been DEPRECATED as of PHP 7.2.0. Relying on this function is highly discouraged.
You can use the array_map() function.
This should do it:
As @Relequestual writes below, the function is now integrated directly in the array_map. The new version of the solution looks like this:
The solution depends on the PHP version you are using. At least there are 2 solutions:
First (Newer PHP versions)
As @JosepAlsina said before the best and also shortest solution is to use array_column as following:
Second (Older PHP versions)
@Greg said in older PHP versions it is possible to do following:
But beware: In newer PHP versions >= 5.3.0 it is better to use Closure s, like followed:
The difference
First solution creates a new function and puts it into your RAM. The garbage collector does not delete the already created and already called function instance out of memory for some reason. And that regardless of the fact, that the created function instance can never be called again, because we have no pointer for it. And the next time when this code is called, the same function will be created again. This behavior slowly fills your memory.
Both examples with memory output to compare them:
Using php’s array_search on an array of objects
http://php.net/manual/en/function.array-search.php allows me to find the first array key based on an array value.
Can this be accomplished with a single PHP function if the value is nested in an object in the array values, or must it be manually performed as I show below?
2 Answers 2
Just for fun, if the array is 0 based and sequential keys:
This decodes the JSON into an array. You can decode it to an object after if you need that. As of PHP 7 you can use an array of objects:
There’s no single built-in function that provides for arbitrary comparison. You can, however, roll your own generic array search:
This has the benefit of returning an array of matches to the comparison function, rather than a single key which you later have to lookup. It also has performance O(n), which is ok.
Not the answer you’re looking for? Browse other questions tagged php arrays or ask your own question.
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
site design / logo © 2021 Stack Exchange Inc; user contributions licensed under cc by-sa. rev 2021.9.17.40238
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
Делаем из массивов объекты
PHP содержит очень мощный инструмент — массивы. Половина функций в PHP возвращает результат как ассоциативные массивы. При работе с такими функциями легко допустить ошибки в именовании ключей массива. Понятно что для опытного разработчика это не составляет проблем, но для начинающих это частенько может стать головной болью, особенно если мы получаем огромный json или просто правим legasylegacy код, ну а для не программистов… (таких как я) может послужить генератором говнострашного кода.
Тут приведу некий трюк, который позволяет использовать массив как объект/коллекцию. Возможно кому то это покажется глупым, а кому то даст идеи для применения.
Сразу оговорюсь что реализация рабочая для PHPStorm, в других IDE нужно вам проверять.
Часть примеров будет взята с потолка, часть будет взята из Instagram api.
Примеры
Пример 1. Работаем с данными формы.
Ну и результат использования такого «класса»
Сразу видно с чем имеем дело.
Пример 2. Работаем с сессиями.
Нам нужно работать с сессиями максимально просто.
Наш класс:
Класс для сессий (код ArrayClass будет в конце):
Это нам позволяет спокойно работать так:
$s = new MySession();
$s->var1 = 10;
Всё просто и прозрачно.
Пример 3. Instagram, json и сложные массивы
Нам нужно вызвать API. Делаем это примерно так:
Как это выглядит в IDE:
В 2х словах. Мы получаем json от Instagram и заворачиваем его в наши классы. На выходе получаем структуру классов и помощь от нашей IDE.
Ну а теперь сам ArrayClass:
Вот что получаем на выходе:
Если у кого нибудь есть дополнения по использованию памяти и производительности прошу отписаться в комментариях. Спасибо.
PHP in_array object comparing?
Can the in_array function compare objects?
For example, I have an array of objects and I want to add them distinctly to another array. Is it possible to check if an object has already been added like so:
or is there any other way?
8 Answers 8
You can use strict comparison:
The in_array function cannot compare objects.
You should create unique key-value pairs from your objects and only need to compare those keys when inserting a new object into your final array.
Assuming that each object has an unique id property, a possible solution would be:
There’s numerous ways you can do this as you can see. I just thought I would add another one. I don’t know why, but when working with object arrays I like to use the array functions which use callbacks.
If your objects have any sort of identifier, which they should if you want to test them for duplication, the following will work:
I did some tests comparing objects with the in_array function. This is my conclusion:
When you try to find the same instance of an object in an array (like OP), then in_array could work with the strict comparison boolean set.
When you try to find any object of the same class but with a different instance, in_array shows counter-intuitive behavior.
There is a great user comment on PHP.net about the counter-intuitive edge cases.
We know from PHP.net that two objects are only the same in strict comparison ( === ) when they are from the same class + instance. Two objects are already the same in loose comparison ( == ) when they are from the same class.
I wrote some tests with objects to see what happens.
The reason is as follow. If you try to find any object with a certain value, you are forced to use loose comparison (because when the class is not the same, strict comparison always fails). But due to PHP’s variable types, in the last tests these checks are considered true, because the value is considered truthy. Also note that the key on the object is ignored in loose comparison.