PHP convert array to resource - php

For visual representation, for simplicity and of course to feed my curiosity, I'm wondering how to convert a PHP array into a valid PHP resource.
See the below example:
(example image created with dBug component available at http://dbug.ospinto.com/)
I've made 3 examples:
resource: this is the typical representation of a MySQL resource, visualized as a grid
object: a handmade create object from an array
array: a handmade multidimensional array
As you can see, the resource is a visual beauty, while the object and array are constructed by using multidimensional arrays, using poor numeric array indexes to bind them together :(
What I'm looking for, would probably be something like this:
$resource_var = (resource) $array_var;

What I'm looking for, would probably something like this:
$resource_var = (resource) $array(var)
You will never find that. A resource is an internal data-type in PHP. If (and only if) you write yourself a PHP extension and load it, you could do the following:
$resource = array_resource_create($array);
Your PHP extension then would create that resource (as the mysql extension for example creates its specific resource type) within that array_resource_create function. However, it would be useless, because there is no other function so far that could deal with that resource.

You can't create resource. but you can use native one.
Try with curl for example.
function makeResourceFromArray($array) {
$resource = curl_init();
curl_setopt($resource, CURLOPT_PRIVATE, serialize($array));
return $resource;
}
function makeArrayFromResource($resource) {
return unserialize(curl_getinfo($resource, CURLINFO_PRIVATE));
}
$resource = makeResourceFromArray(['name' => 'test']);
$array = makeArrayFromResource($resource);

The output you show there is nothing to do with it being a resource as such, but the pretty-print function you're using noticing that the variable you've given it points at a database result set, and fetching and displaying the results.
What PHP means by a resource is that the variable doesn't actually hold data within PHP, but is a pointer or reference usable by some lower-level module of code - in this case, a DB library which can use that reference to retrieve the results of the executed query.
If you just want the pretty-print to look similar for an array with a DB-resultset-like structure, then you should simply modify the pretty-print function to do so - you don't need to do anything to the array itself.

A resource is a special type. And a resource is specific to a source that's external. Therefore going backwards wouldn't be possible.
Theoretically, an interface with an instance of the resource would help manage the type - but this is just nonsense theoretical talk that is impossible in PHP.

Related

PHP objecture structure chainability

I am trying to build a huge object structure that depends on hundreds of queries. To make it performant i did the following approach:
Each query result object is build into an object. For example a result set from table "apples" is build into an apple object. An orange result is build into an orange object.
Each object is saved in the registry, where the registry is a global array with functions like isExistent($type, $id), add($type, $obj) and get($type, $id). I want to store each object from point 1 once here to access it later without needing to call another query for the object (tons of objects are needed several times at different places).
I want objects to be chained together so i can do something like $tree->getFruits()->getApple()->getPlace()->getName(). I also want objects in my hierarchy to be linked in both directions for later use.
Why do i need this? For example the "apple" object with id 3 will be used once when the $tree object is instantiated, once when the $vitamins object is created, etc. I don't want to sent another query() each time to the database this object is needed. So i check something like:
Registry::isExistent("APPLE", $id)
and then get it from the Registry if it is there, and otherwise call it from db and then additionally add it to registry.
Problem: I am getting infinite loops for obvious reasons, which i could easily fix, but i don't know what's the best approach here.
Actual Code (not example stuff like apples and oranges from above):
$mask = new Mask($row["maskId"], $row["maskName"]);
foreach (Fields::getFieldsFor($mask->getId()) as $field) {
$mask->addField($field);
}
Registry::add("MASK", $mask);
and the getter for a field of a mask:
$mask = Registry::receive("MASK", $row["maskId"]);
$category = Registry::receive("FIELDTYPE", $row["fieldCategory"]);
$field = new Field($row["fieldId"], $category, $row["fieldQuestion"],
$row["fieldDescription"], $row["fieldPosition"], null, null, null, $mask);
Registry::add("FIELD", $field);
This will produce an infinite loop. A mask consists of several fields. When building the $mask object i want to have each field linked in the $mask array. When building each $field object i want to parent $mask linked to it. This will obviously fail because i only add to registry, AFTER they are done building which will obviously fail because before that they will already have a look at the registry.
There are 2 solutions i can think of:
Throw away my chainability and simply store the linked ids in my objects. So instead of storing a reference to the parent mask object in each field i would simply store the id and later retreive the actual object from the registry. This would be the easiest fix, but would throw away the chainability.
Split up the primitive object instantiation and the complex attributes. Just add the primitives via the constructor and add the complex like the actual $mask object to each field after the constructor AND after the Registry::add() via a setter.
What would be best to do here? Is something wrong in my general approach?
My goal simply is to build an easy to work with object structure (will be hundreds of objects) and to reduce redundant queries(). This really needs to be fast. I also only want each different object once and then linked accordingly in the complex object structure.
Thanks and sorry for a long description.
well, i've done something similar for one project few years ago using PHP Magic Method __get(). What i've done actually is storing the Getter Object inside a variable called Registry.get; something like: $this->get = new GetterObject($this);. Now, notice that i passed the Registry as a variable to my GetterObject, you might ask "why?" simply this is:
How it Works
The GetterObject gets initialized with the Registry as a variable (unless Registery as a global absolute object then no need for this!).
You "get" a ORM-object using something like Registery::get->fruits;.
The GetterObject will check the Registry array of objects to find fruits ORM-object.
The GetterObject will return a new instance of itself with some additional variables defining at which step you are; something like $this->path = "/fruits/";.
Now, when you "get" the second object, say, Registery::get->fruits->apples;, the GetterObject will simple check which was the last $this->path piece, on which it will depend to find the child element. Note that this step depends highly on how you structured your own ORM-objects array.
The GetterObject will repeat steps 4, and 5 until you end up with the object of desire and do something like ->return_values(); which is a defined function that returns the actual ORM-object you are looking for, not the GetterObject you were using to navigate through your ORM-objects.
As a small note again, this might not be the best practice for all the Registry-based platforms, so, make sure you really need something this complicated before doing so. Otherwise, a simple __get() definition might all what you need. Best of Luck.

Single array element becomes object with Zend_Soap_Client

I'm using Zend_Soap_Client and encountering this issue:
<parent>
<child><name>abc</name></child>
<child><name>def</name></child>
</parent>
If there's more than one child element then Zend return array and I can access like
$result->parent->child[0]->name
but if there's only one child node it returns object like:
$result->parent->child->name
Can you please let me know what's wrong with my approach or how can I overcome it?
My sample code:
$client = new Zend_Soap_Client('url', array('wsdl'=>'url));
$result = $client->getResult();
I'm using zend 1.9. The same issue happens with PHP's native SoapClient
Thanks!
Personally I do not see the need to use Zend_Soap_Client instead of SoapClient because the Zend version does not add anything beneficial, but on the other hand the solution applies to both:
There is an options array parameter in the original SoapClient that accepts plenty of things, and especially this below (ref):
The features option is a bitmask of SOAP_SINGLE_ELEMENT_ARRAYS,...
With this option, all array structures in the soap response are not reduced to one single element if they contain only one, but left as is. You are always accessing an array then, which is easier than switching depending on the content.
Example:
$s = new SoapClient($wsdl, array('features' => SOAP_SINGLE_ELEMENT_ARRAYS));

Why would one want to pass primitive-type parameters by reference in PHP?

One thing that's always bugged me (and everyone else, ever) about PHP is its inconsistency in function naming and parameters. Another more recent annoyance is its tendency to ask for function parameters by reference rather than by value.
I did a quick browse through the PHP manual, and found the function sort() as an example. If I was implementing that function I'd take an array by value, sort it into a new array, and return the new value. In PHP, sort() returns a boolean, and modifies the existing array.
How I'd like to call sort():
$array = array('c','a','b');
$sorted_array = sort($array);
How PHP wants me to call sort():
$array = array('c','a','b');
sort($array);
$sorted_array = $array;
And additionally, the following throws a fatal error: Fatal error: Only variables can be passed by reference
sort(array('c','a','b');
I'd imagine that part of this could be a legacy of PHP's old days, but there must have been a reason things were done this way. I can see the value in passing an object by reference ID like PHP 5+ does (which I guess is sort of in between pass by reference and pass by value), but not in the case of strings, arrays, integers and such.
I'm not an expert in the field of Computer Science, so as you can probably gather I'm trying to grasp some of these concepts still, and I'm curious as to whether there's a reason things are set up this way, or whether it's just a leftover.
The main reason is that PHP was developed by C programmers, and this is very much a C-programming paradigm. In C, it makes sense to pass a pointer to a data structure you want changed. In PHP, not so much (Among other things, because references are not the same as a pointer).
I believe this is done for speed-reason.
Most of the time you need the array you are working on to be sorted, not a copy.
If sort should have returned a new copy of the array then for each time you call sort(); the PHP engine should have copied the array into new one (lowering speed and increasing space cost) and you would have no way to control this behaviour.
If you need the original array to be not sorted (and this doesn't happen so often) then just do:
$copy = $yourArray;
sort($yourArray);

Should I create wrappers for all my RESTful JSON exchanges?

I have multiple calls to many RESTful services. I translate to PHP using native PHP json_decode when I receive the data, and use json_encode when sending data.
My concern is that with deeply nested data I end up writing code like:
$interestType = $person['children'][$i]['interests'][$j]['type'];
This can get quite messy. I feel there would be some benefit in creating objects whose methods/instance variables wrap around these structures, such that I could do:
$interestType = $person->getChild($i)->getInterest($j)->getType();
It seems clearer to me, but in reality it's not much more concise.
What are the benefits of just doing everything using native PHP arrays, and writing wrapper classes for each REST resource?
My concern is that I will have to write custom encode/decode functions to map to these wrappers.
I am not familiar with the implementation of objects in PHP, but reading this blogpost about array vs object performance, it seems the overhead is minimal. So I guess it boils down to style preferences. A simple (not-nested) array to object converter can be found here:
http://www.lost-in-code.com/programming/php-code/php-array-to-object/
A compromise, which would be trivial to implement:
<?php
$json = '{"a": [{"aa" : 11}, {"ab" : 12}],"b":2,"c":3,"d":4,"e":5}';
$o = json_decode($json); // plain object
$a = json_decode($json, true); // this will yield an array
echo $o->a[0]->aa;
?>
json_decode takes an optional argument, that determines, if the supplied JSON is converted to an associative array. If it isn't ($o), you have half the syntax, you aim for.

Does foreach always create a copy on a none reference in PHP?

I'm wondering if PHP has this optimization built in. Normally when you call foreach without using a reference it copies the passed array and operates on it. What happens if the reference count to that array is only 1?
Say for example if getData returns some array of data.
foreach(getData() as $data)
echo $data;
Since the array returned by getData() only has one reference shouldn't it just be used by reference and not copied first or does php not have this optimization?
This seems like a simple optimization that could help a lot of badly written code.
I can't say for certain, but PHP normally uses "copy on write", so everything is a reference until you try to write to it, at which time a copy is made and you write to the copy.

Categories