Storing values in PHP - php

I am trying to store values in php, like a HashTable with multiple keys. For example I am I would want this to return two different values:
$value1=$content['var1']['var2']['var3']['typea'];
$value2=$content['var1']['var2']['var3']['typeb'];
What would be the best way to go about implementing a feature like this?

Instead of building a complicated array, how about you define and use a simple class instead? e.g:
<?php
class beer {
var $brand;
var $ounces;
var $container;
}
$mybeer = new beer();
$mybeer->brand = "Coors";
$mybeer->ounces = 12;
$mybeer->container = "can";
echo $mybeer->brand;
echo $mybeer->ounces;
echo $mybeer->container;
?>

You can set values the same way you get them.
$content['var1']['var2']['var3']['typea'] = $value1;
$content['var1']['var2']['var3']['typeb'] = $value2;

You can take advantage of PHP being a dynamic scripting language by letting it create your desired array structure automatically:
$content['var1']['var2']['var3']['typea'] = "value1";

One way would be to make a unique key based on the various keys and store it in one big array.
Instead of this,
$value1=$content['var1']['var2']['var3']['typea'];
you'd have something like this...
$contentKey = generateKey("var1", "var2", "var3", "typeA");
$value1 = $content[$contentKey];
where generateKey would do something like hash the various inputs, or concatenate them together with some unique delimiter like a quadruple underscore. This would require fewer array lookups than the other solutions, and (in my opinion) is easier to read.

Related

What is the fastest way to pass database cell values to many different PHP variables?

I have an Oracle database which serves as an array of ~70 values. I am trying to find the most efficient code to pass each cell value to a variable, preferebly coded in PHP.
Example:
Cell1 Cell2 Cell3 Cell4 ... Cell70
Pass each cell 1-70 to a variable named after that cell:
($CELL1, $CELL2, $CELL3, $CELL4 ... $CELL70)
I can think of no practical reason to use multiple variables over an array, but you could in theory use variable variables:
for ($i = 0; $i < count($arr); $i++) {
${"Cell" + $i} = $arr[$i];
}
Instead it would be much simpler to just use $arr["Cell1"] in spots where you may want to use $Cell1.
It'd be FAR simpler to just use an array:
$arr = oci_fetch_array(...);
so you don't pollute the namespace with a bunch of (mostly) useless variables.
If you INSIST on going this route, then you could try:
list($cell1, $cell2, $cell3, ...., $cellWayTooManyCells) = oci_fetch_array(...);
Or
$arr = oci_fetch_assoc(...);
extract($arr);

Creating an array in PHP

If I wanted to create an array in PHP with the following format, what would be the best way to approach it? Basically I want to declare the array beforehand, and then be able to add the values to person_id, name and age.
'person_id' => array('name'=>'jonah', 'age'=> 35)
To the first answer #Joe, first of all, your class doesn't support encapsulation since your attributes are public. Also, for someone who doesn't know how to create an array, this concept may be a bit complicated.
For the answer, changing a bit the class provided by #Joe, PHP provide a simple way of using arrays:
If you need many rows for this array, each row has a number, if not, remove the [0] for only one entry.
$persons = array();
$persons[0]['person_id'] = 1;
$persons[0]['name'] = 'John';
$persons[0]['age'] = '27';
Depending on how you want to use it, you could make a simple object:
class Person
{
public $person_id;
public $name;
public $age;
}
$person = new Person; // make the object beforehand
$person->person_id = 123; // their id
$person->name = 'Joe'; // my name
$person->age = 21; // yeah, right
This is virtually identical to an array (in terms of how it's used) except for:
Instead of new array() you use new Person (no brackets)
Instead of accessing items with ['item'] you use ->item
You can start with an empty array:
$arr = Array();
Then add stuff to that array:
$arr['person_id'] = Array();
$arr['person_id']['name'] = "jonah";
$arr['person_id']['age'] = 35;

Does php have c++'s std::pair?

I'd like to make an associative array in PHP where the key is a pair of strings.
At first I was considering concatenating the strings with some sort of unique divider in the middle, and then separating them later, but this seems like a hacky workaround for using a pair.
Consider the following code:
$andrew = array('Andrew', 'Rasmussen');
$john = array('John', 'Smith');
$container[$andrew] = 15;
$container[$john] = 12;
$pair = array('Andrew', 'Rasmussen');
if (array_key_exists($pair, $container)) {
echo 'true';
} else {
echo 'false';
}
Obviously this code will not work because you can't use an array as a key in an array in PHP. Is there a good way to do something like this without concatenating and then later parsing the strings?
Edit
I have a reason for wanting to do this. I have an array(key=string1,value=array(key=string2,value=occurrences)) and I'm trying to find the top 5 (in terms of occurrences) of string pairs. So I'm basically trying to flatten this into a 1d array and then sort it so I can easily grab the top 5. But to do this I'll need to be able to extract the strings out separately after I've sorted, which can be done with the divider algorithm explained above, but this is not preferable, which is why I'm asking for an alternative.
How about serializeing the key?
$pair = array('Andrew', 'Rasmussen');
if (array_key_exists( serialize( $pair), $container)) {
echo 'true';
} else {
echo 'false';
}
You can make use of multidimensional arrays (by using it as $container["Andrew"]["Rasmussen"] for example).
Also, you can encapsulate all the "hacking" (be it two-dimensional arrays or string concatenation) in your custom ArrayIndexedByPairs class, which could be like the following:
interface IArrayIndexedByPairs {
public Add($key1, $key2, $value);
public Contains($key1, $key2);
public Get($key1, $key2);
}

PHP Date merging class / method?

I am doing work where I get data in various formats from various sources. I will end up with something like this:
$dataSource1 = ... ;
$dataSource2 = ... ;
$dataSource3 = ... ;
I need to COMBINE these data sources, all with different field names, into one object, that I can sort according to fields, limit to X number etc.... all for display purposes.
What is the best way to do this? Is there a good php library that does this?
Three possible solutions,
You could always create a database and just use that. (Probably the best thing to do)
Alternatively, you could try attempt to do some polymorphisisng? (cant be made into a verb!)
Finally, you could also include all the other pages into the one you will be displaying from.
(I suggest number 1)
I think the simplest way is using an associative array.
$dataSource1 = ...;
$dataSource2 = ...;
...
$dataSourceN = ...;
$data = array()
$data[0] = $dataSource1;
$data[1] = $dataSource2;
And so on. Just remember that a numeric index array always starts at 0. So the first element would be $data[0].
If you want a more complex bind you can create a multidimensional array. It means you can sort by specific fields. See an example:
$data1 = 'Brazil';
$dataArray = array()
$dataArray[] = array(
'countryId' => 'id',
'countryName' => $data1,
'usersFromThisCountry' => $data1Users
);
Now you can sort $dataArray according to 'countryId','countryName','usersFromThisCountry'.

Autofill array with empty data to match another array size

I have 2 sets of arrays:
$dates1 = array('9/12','9/13','9/14','9/15','9/16','9/17');
$data1 = array('5','3','7','7','22','18');
// for this dataset, the value on 9/12 is 5
$dates2 = array('9/14','9/15');
$data2 = array('12','1');
As you can see the 2nd dataset has fewer dates, so I need to "autofill" the reset of the array to match the largest dataset.
$dates2 = array('9/12','9/13','9/14','9/15','9/16','9/17');
$data2 = array('','','12','1','','');
There will be more than 2 datasets, so I would have to find the largest dataset, and run a function for each smaller dataset to properly format it.
The function I'd create is the problem for me. Not even sure where to start at this point. Also, I can format the date and data arrays differently (multidimensional arrays?) if for some reason that is better.
You can do this in a pretty straightforward manner using some array functions. Try something like this:
//make an empty array matching your maximum-sized data set
$empty = array_fill_keys($dates1,'');
//for each array you wish to pad, do this:
//make key/value array
$new = array_combine($dates2,$data2);
//merge, overwriting empty keys with data values
$new = array_merge($empty,$new);
//if you want just the data values again
$data2 = array_values($new);
print_r($data2);
It would be pretty easy to turn that into a function or put it into a for loop to operate on your array sets. Turning them into associative arrays of key/value pairs would make them easier to work with too I would think.
If datas are related will be painful to scatter them on several array.
The best solution would be model an object with obvious property names
and use it with related accessor.
From your question I haven't a lot of hint of what data are and then I have to guess a bit:
I pretend you need to keep a daily log on access on a website with downloads. Instead of using dates/data1/data2 array I would model a data structure similar to this:
$log = array(
array('date'=>'2011-09-12','accessCount'=>7,'downloadCount'=>3),
array('date'=>'2011-09-13','accessCount'=>9), /* better downloadsCount=>0 though */
array('date'=>'2011-09-15','accessCount'=>7,'downloadCount'=>3)
...
)
Using this data structure I would model a dayCollection class with methods add,remove,get,set, search with all methods returning a day instance (yes, the remove too) and according signature. The day Class would have the standard getter/setter for every property (you can resolve to magic methods).
Depending on the amount of data you have to manipulate you can opt to maintain into the collection just the object data (serialize on store/unserialize on retrieve) or the whole object.
It is difficult to show you some code as the question is lacking of details on your data model.
If you still want to pad your array than this code would be a good start:
$temp = array($dates, $data1, $data2);
$max = max(array_map('count',$temp));
$result = array_map( function($x) use($max) {
return array_pad($x,$max,0);
}, $temp);
in $result you have your padded arrays. if you want to substitute your arrays do a simple
list($dates, $data1, $data2) = array_map(....
You should use hashmaps instead of arrays to associate each date to a data.
Then, find the largest one, cycle through its keys with a foreach, and test the existence of the same key in the small one.
If it doesn't exist, create it with an empty value.
EDIT with code (for completeness, other answers seem definitely better):
$dates_data1 = array('9/12'=>'5', '9/13'=>'3', '9/14'=>'7' /* continued */);
$dates_data2 = array('9/14'=>'12', '9/15'=>'1');
#cycle through each key (date) of the longest array
foreach($dates_data1 as $key => $value){
#check if the key exists in the smallest and add '' value if it does not
if(!isset( $date_data2[$key] )){ $date_data2[$key]=''; }
}

Categories