What I want to attempt:
class thing{
public $name = "default";
public $stats = [1,2];
}
$myArray = (object)array(new thing,'internalArray'=>[(object)[],new thing]) //un-named objects in a complex array/object
There are a great number of ways to 'put' objects in arrays. The question I ask is to where the boundaries and limits are in putting objects in new arrays. This particular question may not lead to the most effective answer for many readers but it will at least clear up why(for me) a new object is/isn't good practice in an initialized array.
In searching through the PHP Manual, Stack Overflow, and ... W3Schools - I've found little to nothing that helps with this specific case, depending on how you perceive the lack of examples. No info could just mean that this is "a dumb idea" and one should never mind themselves with it.
It is certainly possible to initialise an array with objects in it.
Whether that's "okay" probably depends on whose judgement you prefer, and/or which goal you try to achieve. I'd personally optimise for readability first; from that perspective "initialising an array with objects in it" could certainly be a valid choice.
In terms of readability, however, I must say I find the example rather confusing. I see an array that has a mix of numeric and some associative indices, which gets converted to a standard object. If readability is the goal, there are probably better ways to express the intent of the code.
I'm currently working on a project which requires me to only output objects when querying database and/or processing data. I have been hearing from other senior developers that, objects are "cheap" in term of memory and, I "kind of" agree with that.
So, my questions:
If I have an array as result of a query. Why not use the array "as is" since it already exists?
Is it really a good practice (besides standardization) to convert it into an object?
Does it really increase performance? (I can't grasp it because by converting the result into an object, I'm basically creating another entity, besides the already existing array, containing the same data).
In my opinion, I would say that you should NOT convert them into objects.
You already have them as arrays, so transforming/copying them into object would require more memory as at a given time, you end up with both, the objects and arrays. If you absolutely do not need any OOP functionality (inheritance, private proprieties/methods, ...) you should stick with your arrays.
But keep in mind: You can often fetch the database and get objects instead of arrays as result. (See PDO fetchAll) Then you already have your objects without having the array.
If you wonder how these both parties work in terms of performance, have a look at
Using arrays VS objects for storing data.
From what I understand, (but I might as well be wrong) PHP arrays are not arrays compared to the classical C arrays. A PHP array is a sort of object, since you have freedoms to i.e. change an array size (simply add a value). So you do not have the exact same performance as you would have with C arrays.
Conclusion: Feel free to keep your arrays. If you do not need the advantages of objects, no need to use ressources to convert them. After all, it's also a question of programming style, best practices and project guidelines.
It depends on what next is the code doing with the array.
If you leave the data in array you should be careful where you pass it next, because you do not want that array go all over the code base back and forth.
With array you cannot define any definable interface between classes or logic code blocks and that is not very predictable.
When you have array passed through 10 methods in 5 classes modifying the contents of that array its very hard to track what and where is happening to the contents.
I like this answer: https://www.reddit.com/r/PHP/comments/29eope/stop_abusing_arrays_in_php/cik8tet/
Might not be a question specific to Eloquent collections, but it just hit me while working with them. Let's just assume we have a $collection object which is an instance of Illuminate\Support\Collection.
Now if we want to iterate over it, what are the pros and cons of using each() with a closure versus a regular foreach. Are there any?
foreach ($collection as $item) {
// Some code
}
versus
$collection->each(function ($item) {
// Some code
});
A foreach statement should be used as a sort of a way to cycle through a collection and perform some sort of logic on it. If what is in it effects other things in the program, then use this loop.
The .each method uses array_map to cycle through each of the objects in the collection and perform a closure on each one. It then returns the resulting array. That is the key! .each should be used if you want to change the collection in some way. Maybe it's an array of cars and you want to make the model upper case or lower case. You would just pass a closure to the .each method that takes the object and calls strtoupper() on the model of each Car object. It then returns the collection with the changes that have been made.
Morale of the story is this: use the .each method to change each item in the array in some way; use the foreach loop to use each object to affect some other part of the program (using some logic statement).
UPDATE (June 7, 2015)
As stated so Eloquently (see what I did there?) below, the above answer is slightly off. The .each method using array_map never actually used the output from the array_map call. So, the new array created by array_map would not be saved on the Collection. To change it, you're better off using the .map method, which also exists on a Collection object.
Using a foreach statement to iterate over each of them makes a bit more sense because you won't be able to access variables outside the Closure unless you make sure to use a use statement, which seems awkward to me.
The implementation when the above answer was originally written can be found here.
.each in Laravel 5.1
The new .each that they are talking about below no longer uses array_map. It simply iterates through each item in the collection and calls the passed in $callback, passing it the item and its key in the array. Functionally, it seems to work the same. I believe using a foreach loop would make more sense when reading the code. However, I see the benefits of using .each because it allows you to chain methods together if that tickles your fancy. It also allows you to return false from the callback to leave the loop early if your business logic demands you to be able to.
For more info on the new implementation, check out the source code.
There is a lot of confusing misinformation in the existing answers.
The Short Answer
The short answer is: There is no major difference between using .each() vs. foreach to iterate over a Laravel collection. Both techniques achieve the same result.
What about modifying items?
Whether or not you're modifying items is irrelevant to whether you use .each() vs. foreach. They both do (and don't!) allow you to modify items in the collection depending on what type of items we're talking about.
Modifying items if the Collection contains objects: If the Collection is a set of PHP objects (such as an Eloquent Collection), either .each() or foreach allow you to modify properties of the objects (such as $item->name = 'foo'). That's simply because of how PHP objects always act like references. If you're trying to replace the entire object with a different object (a less common scenario), use .map() instead.
Modifying items if the Collection contains non-objects: This is less common, but if your Collection contains non-objects, such as strings, .each() doesn't give you a way to modify the values of the collection items. (The return value of the closure is ignored.) Use .map() instead.
So... which one should I use?
In case you're wondering about performance, I did several tests with large collections of both Eloquent items and a collection of strings. In both cases, using foreach was faster than .each(). But we're talking about microseconds. In most real-life scenarios the speed difference wouldn't be significant compared to the time it takes to access the database, etc.
It mostly comes down to your personal preference. Using .each() is nice because you can chain several operations together (for example .where(...).each(...)). I tend to use both in my own code just depending on what seems the cleanest for each situation.
Contrary to what the two other answers say, Collection::each() does not change the values of the items in the Collection, technically speaking. It does use array_map(), but it doesn't store the result of that call.
If you want to modify each item in a collection (such as to cast them to objects as Damon in a comment to the crrently accepted answer), then you should use Collection::map(). This will create a new Collection based on the result of the underlying call to array_map().
It is more beneficial to use the latter: each().
You can chain conditions and write clearer more expressive code, eg:
$example->each()->map()->filter();
This takes you closer to Declarative Programming where you tell the computer what to accomplish instead of how to accomplish.
Some useful articles:
https://martinfowler.com/articles/collection-pipeline/
https://adamwathan.me/refactoring-to-collections/
->each() is the same as foreach(...) but worse.
The main difference here is Variable scope.
In classical foreach you can easily operate variables declared before the foreach. If you are dealing with closure, you would need to inheriting variables from the parent scope with use. This feature is confusing, because when you use it, your function becomes scope dependant...
You can chain ->each() with other functions, but since it does not change the values in the collection, it has very limited use case. And because it is "rare to use", it is not always easily recognizable by developers when they read your code.
Not many people will read your code, cherish those who will.
The foreach() construct does not allow you to change the value of the array item being iterated over, unless you pass the array by reference.
foreach ($array as &$value) $value *= $value;
The each() eloquent method wraps the PHP array_map() function, which allows this.
Like the previous answer states, you should use foreach() if you have any other motivation. This is because the performance of foreach() is much better than array_map().
http://willem.stuursma.name/2010/11/22/a-detailed-look-into-array_map-and-foreach/
I do a lot of work in WordPress, and I've noticed that far more functions return objects than arrays. Database results are returned as objects unless you specifically ask for an array. Errors are returned as objects. Outside of WordPress, most APIs give you an object instead of an array.
My question is, why do they use objects instead of arrays? For the most part it doesn't matter too much, but in some cases I find objects harder to not only process but to wrap my head around. Is there a performance reason for using an object?
I'm a self-taught PHP programmer. I've got a liberal arts degree. So forgive me if I'm missing a fundamental aspect of computer science. ;)
These are the reasons why I prefer objects in general:
Objects not only contain data but also functionality.
Objects have (in most cases) a predefined structure. This is very useful for API design. Furthermore, you can set properties as public, protected, or private.
objects better fit object oriented development.
In most IDE's auto-completion only works for objects.
Here is something to read:
Object Vs. Array in PHP
PHP stdClass: Storing Data in an Object Instead of an Array
When should I use stdClass and when should I use an array in php5 oo code
PHP Objects vs Arrays
Mysql results in PHP - arrays or objects?
PHP objects vs arrays performance myth
A Set of Objects in PHP: Arrays vs. SplObjectStorage
Better Object-Oriented Arrays
This probably isn't something you are going to deeply understand until you have worked on a large software project for several years. Many fresh computer science majors will give you an answer with all the right words (encapsulation, functionality with data, and maintainability) but few will really understand why all that stuff is good to have.
Let's run through a few examples.
If arrays were returned, then either all of the values need to be computed up front or lots of little values need to be returned with which you can build the more complex values from.
Think about an API method that returns a list of WordPress posts. These posts all have authors, authors have names, e-mail address, maybe even profiles with their biographies.
If you are returning all of the posts in an array, you'll either have to limit yourself to returning an array of post IDs:
[233, 41, 204, 111]
or returning a massive array that looks something like:
[ title: 'somePost', body: 'blah blah', 'author': ['name': 'billy', 'email': 'bill#bill.com', 'profile': ['interests': ['interest1', 'interest2', ...], 'bio': 'info...']] ]
[id: '2', .....]]
The first case of returning a list of IDs isn't very helpful to you because then you need to make an API call for each ID in order to get some information about that post.
The second case will pull way more information than you need 90% of the time and be doing way more work (especially if any of those fields is very complicated to build).
An object on the other hand can provide you with access to all the information you need, but not have actually pulled that information yet. Determining the values of fields can be done lazily (that is, when the value is needed and not beforehand) when using an object.
Arrays expose more data and capabilities than intended
Go back to the example of the massive array being returned. Now someone may likely build an application that iterates over each value inside the post array and prints it. If the API is updated to add just one extra element to that post array then the application code is going to break since it will be printing some new field that it probably shouldn't. If the order of items in the post array returned by the API changes, that will break the application code as well. So returning an array creates all sorts of possible dependencies that an object would not create.
Functionality
An object can hold information inside of it that will allow it to provide useful functionality to you. A post object, for instance, could be smart enough to return the previous or next posts. An array couldn't ever do that for you.
Flexibility
All of the benefits of objects mentioned above help to create a more flexible system.
My question is, why do they use objects instead of arrays?
Probably two reasons:
WordPress is quite old
arrays are faster and take less memory in most cases
easier to serialize
Is there a performance reason for using an object?
No. But a lot of good other reasons, for example:
you may store logic in the objects (methods, closures, etc.)
you may force object structure using an interface
better autocompletion in IDE
you don't get notices for not undefined array keys
in the end, you may easily convert any object to array
OOP != AOP :)
(For example, in Ruby, everything is an object. PHP was procedural/scripting language previously.)
WordPress (and a fair amount of other PHP applications) use objects rather than arrays, for conceptual, rather than technical reasons.
An object (even if just an instance of stdClass) is a representation of one thing. In WordPress that might be a post, a comment, or a user. An array on the other hand is a collection of things. (For example, a list of posts.)
Historically, PHP hasn't had great object support so arrays became quite powerful early on. (For example, the ability to have arbitrary keys rather than just being zero-indexed.) With the object support available in PHP 5, developers now have a choice between using arrays or objects as key-value stores. Personally, I prefer the WordPress approach as I like the syntactic difference between 'entities' and 'collections' that objects and arrays provide.
My question is, why do they (Wordpress) use objects instead of arrays?
That's really a good question and not easy to answer. I can only assume that it's common in Wordpress to use stdClass objects because they're using a database class that by default returns records as a stdClass object. They got used to it (8 years and more) and that's it. I don't think there is much more thought behind the simple fact.
syntactic sugar for associative arrays
-- Zeev Suraski about the standard object since PHP 3
stdClass objects are not really better than arrays. They are pretty much the same. That's for some historical reasons of the language as well as stdClass objects are really limited and actually are only sort of value objects in a very basic sense.
stdClass objects store values for their members like an array does per entry. And that's it.
Only PHP freaks are able to create stdClass objects with private members. There is not much benefit - if any - doing so.
stdClass objects do not have any methods/functions. So no use of that in Wordpress.
Compared with array, there are far less helpful functions to deal with a list or semi-structured data.
However, if you're used to arrays, just cast:
$array = (array) $object;
And you can access the data previously being an object, as an array. Or you like it the other way round:
$object = (object) $array;
Which will only drop invalid member names, like numbers. So take a little care. But I think you get the big picture: There is not much difference as long as it is about arrays and objects of stdClass.
Related:
Converting to object PHP Manual
Reserved Classes PHP Manual
What is stdClass in PHP?
The code looks cooler that way
Objects pass by reference
Objects are more strong typed then arrays, hence lees pron to errors (or give you a meaningful error message when you try to use un-existing member)
All the IDEs today have auto-complete, so when working with defined objects, the IDE does a lot for you and speeds up things
Easilly encapsulate logic and data in the same box, where with arrays, you store the data in the array, and then use a set of different function to process it.
Inheritance, If you would have a similar array with almost but not similar functionality, you would have to duplicate more code then if you are to do it with objects
Probably some more reason I have thought about
Objects are much more powerful than arrays can be.
Each object as an instance of a class can have functions attached.
If you have data that need processing then you need a function that does the processing.
With an array you would have to call that function on that array and therefore associate the logic yourself to the data.
With an object this association is already done and you don't have to care about it any more.
Also you should consider the OO principle of information hiding. Not everything that comes back from or goes to the database should be directly accessible.
There are several reasons to return objects:
Writing $myObject->property requires fewer "overhead" characters than $myArray['element']
Object can return data and functionality; arrays can contain only data.
Enable chaining: $myobject->getData()->parseData()->toXML();
Easier coding: IDE autocompletion can provide method and property hints for object.
In terms of performance, arrays are often faster than objects. In addition to performance, there are several reasons to use arrays:
The the functionality provided by the array_*() family of functions can reduce the amount of coding necessary in some cases.
Operations such as count() and foreach() can be performed on arrays. Objects do not offer this (unless they implement Iterator or Countable).
It's usually not going to be because of performance reasons. Typically, objects cost more than arrays.
For a lot of APIs, it probably has to do with the objects providing other functionality besides being a storage mechanism. Otherwise, it's a matter of preference and there is really no benefit to returning an object vs an array.
An array is just an index of values. Whereas an object contains methods which can generate the result for you. Sure, sometimes you can access an objects values directly, but the "right way to do it" is to access an objects methods (a function operating on the values of that object).
$obj = new MyObject;
$obj->getName(); // this calls a method (function), so it can decide what to return based on conditions or other criteria
$array['name']; // this is just the string "name". there is no logic to it.
Sometimes you are accessing an objects variables directly, this is usually frowned upon, but it happens quite often still.
$obj->name; // accessing the string "name" ... not really different from an array in this case.
However, consider that the MyObject class doesn't have a variable called 'name', but instead has a first_name and last_name variable.
$obj->getName(); // this would return first_name and last_name joined.
$obj->name; // would fail...
$obj->first_name;
$obj->last_name; // would be accessing the variables of that object directly.
This is a very simple example, but you can see where this is going. A class provides a collection of variables and the functions which can operate on those variables all within a self-contained logical entity. An instance of that entity is called an object, and it introduces logic and dynamic results, which an array simply doesn't have.
Most of the time objects are just as fast, if not faster than arrays, in PHP there isn't a noticeable difference. the main reason is that objects are more powerful than arrays. Object orientated programming allows you to create objects and store not only data, but functionality in them, for example in PHP the MySQLi Class allows you to have a database object that you can manipulate using a host of inbuilt functions, rather than the procedural approach.
So the main reason is that OOP is an excellent paradigm. I wrote an article about why using OOP is a good idea, and explaining the concept, you can take a look here: http://tomsbigbox.com/an-introduction-to-oop/
As a minor plus you also type less to get data from an object - $test->data is better than $test['data'].
I'm unfamiliar with word press. A lot of answers here suggest that a strength of objects is there ability to contain functional code. When returning an object from a function/API call it shouldn't contain utility functions. Just properties.
The strength in returning objects is that whatever lies behind the API can change without breaking your code.
Example: You get an array of data with key/value pairs, key representing the DB column. If the DB column gets renamed your code will break.
Im running the next test in php 5.3.10 (windows) :
for ($i = 0; $i < 1000000; $i++) {
$x = array();
$x['a'] = 'a';
$x['b'] = 'b';
}
and
for ($i = 0; $i < 1000000; $i++) {
$x = new stdClass;
$x->a = 'a';
$x->b = 'b';
}
Copied from http://atomized.org/2009/02/really-damn-slow-a-look-at-php-objects/comment-page-1/#comment-186961
Calling the function for 10 concurrent users and 10 times (for to obtain an average) then
Arrays : 100%
Object : 214% – 216% (2 times slower).
AKA, Object it is still painful slow. OOP keeps the things tidy however it should be used carefully.
What Wordpress is applying?. Well, both solutions, is using objects, arrays and object & arrays, Class wpdb uses the later (and it is the heart of Wordpress).
It follows the boxing and unboxing principle of OOP. While languages such as Java and C# support this natively, PHP does not. However it can be accomplished, to some degree in PHP, just not eloquently as the language itself does not have constructs to support it. Having box types in PHP could help with chaining, keeping everything object oriented and allows for type hinting in method signatures. The downside is overhead and the fact that you now have extra checking to do using the “instanceof†construct. Having a type system is also a plus when using development tools that have intellisense or code assist like PDT. Rather than having to google/bing/yahoo for the method, it exists on the object, and you can use the tool to provide a drop down.
Although the points made about objects being more than just data are valid since they are usually data and behaviour there is at least one pattern mentioned in Martin Fowler's "Patterns of Enterprise Application Architecture" that applies to this type of cenario in which you're transfering data from one system (the application behind the API) and another (your application).
Its the Data Transfer Object - An object that carries data between processes in order to reduce the number of method calls.
So if the question is whether APIs should return a DTO or an array I would say that if the performance cost is negligible then you should choose the option that is more maintainable which I would argue is the DTO option... but of course you also have to consider the skills and culture of the team that is developing your system and the language or IDE support for each of the options.
I come from a Java background and have only recently started learning PHP and CodeIgniter.
While I find the framework awesome for its clean design and impressive documentation, I notice that the framework doesn't necessarily discourage the use of data arrays instead of value objects for passing data around. For ex., the database queries return the result in an array which you can then pass over to the views for rendering. Similarly, most of the core library methods take associative arrays as inputs.
This, to me, seems like a bad design for an Object Oriented language which should promote and maybe even enforce using value objects for their obvious benefits of encapsulation.
Is this really an example of bad design or simply a matter of style/preference ? Are there any obvious benefits of using arrays for data over a more OO approach ?
Don't be misled by the myth that "everything has to be an object" for your code to be "good Object Oriented design". When you start trying to formulate rationalisations that "I shouldn't be allowed to do this, because it's not good OOP", you're programming backwards.
When you want a list of pieces of data, a data array will suffice. Indeed, it's appropriate.
Why build a complicated object structure when a hash will do? IMHO, many things in the java world are over-engineered. This opinion seems to be shared with many dynamic languages and toolsets, such as Ruby on Rails.
An array is an object and perfectly valid to use for passing data around. No need to define your own class when a built in one will do.
PHP is not an object oriented language. It's an hybrid language.
Arrays are used everywhere because they are significantly more powerful than in other languages (Java in particular). And behind the scenes both arrays and objects use the same dictionary implementation in PHP.
If you want to objectize arrays, then wrap them in:
$array = new ArrayObject($array, ArrayObject::ARRAY_AS_PROPS);
Or you can just typecast an array 1:1 into an value object:
$obj = (object) $array;
And back:
$array = (array) $obj;
They work alike in quite a few contexts anyway (foreaching over them is easy).
Well, an obvious reason to use value objects instead of associative arrays is that if you're passing data in an array all around the place and then you have to change the name of a db table column, you'll have to update the way you access it everywhere in your code, whereas if you have a value object, you need to update only a one line (inside the VO constructor)