This code was written 10-15 years ago from what I can see. Friday, the webhost stopped supporting php4 and forced upgrade to 5.6.23 and the web app stopped working. I have been going over it all weekend. Got the system running, but there is one serious issue and I've narrowed it to a specific line of code and still can't figure it out due to my not doing php OOP programming myself. Looking for a quick fix here as my friend is dead in the water.
This code:
$ins = & $_SESSION["ins"];
$serv = new Services();
print "post - ";
print_r($_POST)."<br />";
reset($_POST);
foreach ($_POST as $key => $value) {
//$key = addslashes($key);
$query = mysql_query("SELECT $valueNumber
FROM CLIENTS_SERVICES
where serviceID = '$key' and clientID = '$ins->client' and effectiveDate <= '$effectiveDate'
order by effectiveDate DESC LIMIT 1")
or die("SELECT services function query failed!!");
$query_data = mysql_fetch_object($query);
$serv->value = $query_data->$valueNumber;
$serv->quantity = $value;
$ins->services[$key] = $serv; //<----- this is the offender
// Calculate services running total
$total = $total + ($serv->quantity * $serv->value);
print $key." - key<br />";
print $value." - value<br />";
print "serv array - ";
print_r($serv);
print "<br />";
print "ins array - ";
print_r($ins->services);
print "<br />";
print $total." - total<br />";
}
outputs:
post - Array (
[1] =>
[2] =>
[3] =>
[4] =>
[5] =>
[6] => 1.5
[7] =>
[8] =>
[9] =>
[10] =>
[11] =>
[12] =>
[13] =>
[14] =>
[15] =>
[16] => 3
[17] =>
[50] =>
[51] => 1.75
[58] =>
[save_services] => Save )
6 - key
1.5 - value
serv object - Services Object ( [quantity] => 1.5 [value] => 56 )
ins array - Array ( [6] => Services Object ( [quantity] => 1.5 [value] => 56 ) )
84 - total
16 - key
3 - value
serv object - Services Object ( [quantity] => 3 [value] => 45 )
ins array - Array ( [6] => Services Object ( [quantity] => 3 [value] => 45 ) [16] => Services Object ( [quantity] => 3 [value] => 45 ) )
219 - total
51 - key
1.75 - value
serv object - Services Object ( [quantity] => 1.75 [value] => 118 )
ins array - Array ( [6] => Services Object ( [quantity] => 1.75 [value] => 118 ) [16] => Services Object ( [quantity] => 1.75 [value] => 118 ) [51] => Services Object ( [quantity] => 1.75 [value] => 118 ) )
425.5 - total
In a nutshell, I cannot understand why the most recent object values are overwriting the previous array entries. I've spent the weekend trying to figure out what changed between the old version (4.?) and the new 5.6.23, and have been on dozens of dead ends and wild goose chases. Ignorance is not bliss.
If there is a pointer to the resolution, or you can offer some insight, I'd appreciate it.
Create a new instance of services inside of the loop
foreach ($_POST as $key => $value) {
$serv = new Services();
...
}
When you use objects in php it will use the same pointer to that object
Related
I am trying to figure a way to get this to work. But I have a hard time thinking out the logics.
I have this array:
Array
(
[0] => Array
(
[0] => news
[1] => {section}
[2] => {slug}
[3] => {*}
)
[1] => Array
(
[0] => {id}
[1] => {*}
)
[2] => Array
(
[0] => {date}
[1] => 25-07-1982
[2] => {section}
[3] => {slug}
[4] => {*}
)
)
That I need to convert to this result:
0 news/{id}/{date}
1 news/{id}/25-07-1982
2 news/{id}/{section}
3 news/{id}/{slug}
4 news/{id}/{*}
5 news/{*}/{date}
6 news/{*}/25-07-1982
7 news/{*}/{section}
8 news/{*}/{slug}
9 news/{*}/{*}
10 {section}/{id}/{date}
11 {section}/{id}/25-07-1982
12 {section}/{id}/{section}
13 {section}/{id}/{slug}
14 {section}/{id}/{*}
15 {section}/{*}/{date}
16 {section}/{*}/25-07-1982
17 {section}/{*}/{section}
18 {section}/{*}/{slug}
19 {section}/{*}/{*}
20 {slug}/{id}/{date}
21 {slug}/{id}/25-07-1982
22 {slug}/{id}/{section}
23 {slug}/{id}/{slug}
24 {slug}/{id}/{*}
25 {slug}/{*}/{date}
26 {slug}/{*}/25-07-1982
27 {slug}/{*}/{section}
28 {slug}/{*}/{slug}
29 {slug}/{*}/{*}
30 {*}/{id}/{date}
31 {*}/{id}/25-07-1982
32 {*}/{id}/{section}
33 {*}/{id}/{slug}
34 {*}/{id}/{*}
35 {*}/{*}/{date}
36 {*}/{*}/25-07-1982
37 {*}/{*}/{section}
38 {*}/{*}/{slug}
39 {*}/{*}/{*}
The input array could contain more than three keys, so the solution I'm looking for should be dynamic. And the result should have the same order as the result shown above.
Does someone know how to do this in a efficient way? Can someone give me a push in the right direction? Thanks a lot! :)
Sth like this
foreach ($array[0] as $val0 )
foreach ($array[1] as $val1 )
foreach ($array[2] as $val2 )
$newArray[] = "$val0/$val1/$val2";
EDIT: for variable array length
function recursive($array , $length = 0){
$retval =array();
if($length < count($array) -1){
foreach ($array[$length] as $val0 )
foreach (recursive($array, $length+1) as $val1)
$retval[] = "$val0/$val1";
}
else
{
foreach ($array[$length] as $val0 )
$retval[] = "$val0";
}
return $retval;
}
print_r(recursive($array));
Just because I like writing functions that mis/manage PHP arrays, I put this together, mainly because I was pretty sure you could avoid recursion — because the structure itself isn't recursive. (My head seems to think that is a rule, I'm sure someone somewhere can prove it wrong).
foreach ( array_reverse($array) as $sub ) {
if ( isset($rem) ) {
$ret = array();
foreach ( $sub as $itm ) {
foreach ( $rem as $val ) { $ret[] = "$itm/$val"; }
}
$rem = $ret;
}
else {
$rem = $sub;
}
}
The output found in $rem is as follows:
Array (
[0] => news/{id}/{date}
[1] => news/{id}/25-07-1982
[2] => news/{id}/{section}
[3] => news/{id}/{slug}
[4] => news/{id}/{*}
[5] => news/{*}/{date}
[6] => news/{*}/25-07-1982
[7] => news/{*}/{section}
[8] => news/{*}/{slug}
[9] => news/{*}/{*}
[10] => {section}/{id}/{date}
[11] => {section}/{id}/25-07-1982
[12] => {section}/{id}/{section}
[13] => {section}/{id}/{slug}
[14] => {section}/{id}/{*}
[15] => {section}/{*}/{date}
[16] => {section}/{*}/25-07-1982
[17] => {section}/{*}/{section}
[18] => {section}/{*}/{slug}
[19] => {section}/{*}/{*}
[20] => {slug}/{id}/{date}
[21] => {slug}/{id}/25-07-1982
[22] => {slug}/{id}/{section}
[23] => {slug}/{id}/{slug}
[24] => {slug}/{id}/{*}
[25] => {slug}/{*}/{date}
[26] => {slug}/{*}/25-07-1982
[27] => {slug}/{*}/{section}
[28] => {slug}/{*}/{slug}
[29] => {slug}/{*}/{*}
[30] => {*}/{id}/{date}
[31] => {*}/{id}/25-07-1982
[32] => {*}/{id}/{section}
[33] => {*}/{id}/{slug}
[34] => {*}/{id}/{*}
[35] => {*}/{*}/{date}
[36] => {*}/{*}/25-07-1982
[37] => {*}/{*}/{section}
[38] => {*}/{*}/{slug}
[39] => {*}/{*}/{*}
)
Also, for those that like their arrays multidimensional, this might come in handy (although I'd hate to think what the overheads are for such a code golfed version). Just to be clear, this second example doesn't create the string list as requested by the OP, but a hierarchical array structure instead.
foreach ( array_reverse($array) as $sub ) {
$rem = isset($rem)
? array_combine($sub, array_fill(0, count($sub), $rem))
: $sub
;
}
This generates (again in $rem):
Array (
[news] => Array (
[{id}] => Array (
[0] => {date}
[1] => 25-07-1982
[2] => {section}
[3] => {slug}
[4] => {*}
)
[{*}] => Array (
[0] => {date}
[1] => 25-07-1982
[2] => {section}
[3] => {slug}
[4] => {*}
)
)
[{section}] => Array (
[{id}] => Array (
[0] => {date}
[1] => 25-07-1982
[2] => {section}
[3] => {slug}
[4] => {*}
)
... and so on
Now if only PHP had a join_recursive that included keys.
(it would be almost pointless, save for helping with the above).
This question already has answers here:
Sorting an associative array in PHP [duplicate]
(5 answers)
Closed 8 years ago.
I am trying to sort an array by miles.
$i = 0;
foreach($results as $key => $value)
{
echo $results['miles'][$i] . "<br />";
echo $results['postcode'][$i] . "<br />";
echo $results['id'][$i] . "<br />";
echo $results['description'][$i] . "<br />";
echo $results['title'][$i] . "<br />";
echo $results['thumbnail'][$i] . "<br />";
$i++;
}
AS you can see I'm having 6 different keys here. I want to order everything by $results['miles'] in ASCENDING order.
This is my array structure:
Array ( [miles] => Array ( [0] => 0 [1] => 0 [2] => 14 [3] => 8 [4] => 8 [5] => 0 [6] => 8 [7] => 14 ) [title] => Array ( [0] => Stunning 1 Bedroom Apartment With Concierge [1] => Big Double Inc Bills+ Balcony+Free Parking [2] => Large, Sunny Flat In Willesden [3] => Brewhouse Yard EC1V [4] => Stunning 2 Double Bed Flat - City [5] => Room To Let £575 Pm Bills Included [6] => All Bills Inclusive | Gorgeous 1 Bed In The City [7] => Large Double Room In Zone 2 (Kensal Green 2 Mins) ) [id] => Array ( [0] => 187 [1] => 176 [2] => 186 [3] => 178 [4] => 179 [5] => 177 [6] => 183 [7] => 182 ) [thumbnail] => Array ( [0] => [1] => [2] => [3] => [4] => [5] => [6] => [7] => ) [postcode] => Array ( [0] => IG11 [1] => ig11 [2] => NW10 [3] => EC1 [4] => ec1 [5] => ig11 [6] => ec1 [7] => NW10 ) )
Any help would be appreciated!
If you can, the best way is to sort the data before it comes in to your script (if it's coming from SQL then order it there).
If you need to do it in PHP though you can use the uasort function, which allows you to define your own comparison:
function compareMiles($a, $b) {
if ($a['miles'] == $b['miles']) {
return 0;
}
return ($a['miles'] < $b['miles']) ? -1 : 1;
}
uasort($results, 'compareMiles');
You can use usort() function to sort it.
Use asort() to sort an array by maintain index association.
Refer this link for details and example
very basic question however I have had some trouble finding the answers on PHP.NET.
I have the following array:
Array (
[1] => Array
(
[1] => 4
[2] => 1
[3] => 5
[4] => 3
)
[2] => Array
(
[5] => 2
[6] => 8
[7] => 7
[8] => 6
)
[3] => Array
(
[9] => 10
[10] => 9
[11] => 12
[12] => 11
)
[4] => Array
(
[13] => 15
[14] => 16
[15] => 14
[16] => 13
)
)
I want the array to be re-ordered so that the key number 3 in the first series of the array becomes the first, then the rest to be re-ordered from there to eventually get the result of:
Array (
[3] => Array
(
[9] => 10
[10] => 9
[11] => 12
[12] => 11
)
[4] => Array
(
[13] => 15
[14] => 16
[15] => 14
[16] => 13
)
[1] => Array
(
[1] => 4
[2] => 1
[3] => 5
[4] => 3
)
[2] => Array
(
[5] => 2
[6] => 8
[7] => 7
[8] => 6
)
)
I am looking for a way to do this so I can define the array, then the first level key I need to sort by, and then it will return the array in this way.
The standard PHP keys didn't seem to offer something like this, so it would be good to be able to have a separate function such as $newArray = reorder_array($array, $key);
I don't require any sorting of the second level, only the initial 4 main / first level array sections.
You help is greatly appreciated as I have been sitting on this one for awhile without a clear and simple solution.
You re-ordering can be simply implemented with one foreach loop, like:
function reorderArray($array, $key)
{
$found = false;
foreach($array as $k=>$v)
{
$found = $found || $k===$key;
if(!$found)
{
unset($array[$k]);
$array[$k] = $v;
}
//else break can be added for performance issues
}
return $array;
}
with usage
$array=[1=>'foo', 4=>'bar', 9=>'baz', 'test'=>51];
var_dump(reorderArray($array, 9));
var_dump(reorderArray($array, 'test'));
var_dump(reorderArray($array, 'no_such_key'));//original array in result
-check this demo. If keys are consecutive numerics, however, this can be easily implemented with array_slice() calls.
I'm trying to organize my mysql table into a multidimension php tree array.
For example, I'm trying to organize my products in a hierarchy for easy selection to narrow down the result the narrower they go in the result.
I am returned mysql rows like this:
Array
(
[1] => Amazon
[2] => Kindle Fire
[3] =>
[4] =>
[5] =>
[6] =>
[7] =>
[8] =>
[9] => 1
)
Array
(
[1] => Amazon
[2] => Kindle Fire HD
[3] => WiFi
[4] => 7"
[5] =>
[6] => 16GB
[7] =>
[8] =>
[9] => 2
)
Array
(
[1] => Amazon
[2] => Kindle Fire HD
[3] => WiFi
[4] => 7"
[5] =>
[6] => 32GB
[7] =>
[8] =>
[9] => 3
)
Array
(
[1] => Amazon
[2] => Kindle Fire HD
[3] => WiFi
[4] => 8.9"
[5] =>
[6] => 16GB
[7] =>
[8] =>
[9] => 4
)
Array
(
[1] => Amazon
[2] => Kindle Fire HD
[3] => WiFi
[4] => 8.9"
[5] =>
[6] => 32GB
[7] =>
[8] =>
[9] => 5
)
Array
(
[1] => Amazon
[2] => Kindle Fire HD
[3] => 4G LTE
[4] => 8.9"
[5] =>
[6] => 32GB
[7] =>
[8] =>
[9] => 6
)
Array
(
[1] => Amazon
[2] => Kindle Fire HD
[3] => 4G LTE
[4] => 8.9"
[5] =>
[6] => 64GB
[7] =>
[8] =>
[9] => 7
)
Array
(
[1] => Amazon
[2] => Kindle Fire HDX
[3] => Wifi
[4] => 7"
[5] =>
[6] => 16GB
[7] =>
[8] =>
[9] => 8
)
Array
(
[1] => Amazon
[2] => Kindle Fire HDX
[3] => Wifi
[4] => 7"
[5] =>
[6] => 32GB
[7] =>
[8] =>
[9] => 9
)
Array
(
[1] => Amazon
[2] => Kindle Fire HDX
[3] => Wifi
[4] => 7"
[5] =>
[6] => 64GB
[7] =>
[8] =>
[9] => 10
)
...etc
Note the last array value is the Product ID.
And I'm looking for help writing a recursive function that will result in an array that looks like:
Array(
'Amazon' => Array(
'Kindle Fire' => 1,
'Kindle Fire HD' => Array(
'WiFi' => Array(
'7"' => Array(
'16GB' => 2,
'32GB' => 3
)
'8.9"' => Array(
'16GB' => 4,
'32GB' => 5
)
)
)
)
)
I've tried something like:
while($row = mysqli_fetch_row($res)) {
$id = $row[0];
unset($row[0]);
unset($row[count($row)]);
$row[] = $id; // Moves id to last array value
for($i = 1; $i < count($row); $i++) {
if($i == 1) {
if(!array_key_exists($row[$i], $data)) {
// Insert key
$data[$row[$i]] = array();
}
}
else {
$level = $data[$row[$i-1]];
if(array_key_exists($row[$i], $level)) {
// Key exists
}
else {
// Insert key
}
}
}
}
I think your code has a good intention: using $level to hold the current depth. But at the moment this won't work, because you are copying via $level = $data[$row[$i-1]]; - instead you need to refer to it, e.g. with $level =& $data[$row[$i-1]];.
$result = array();
while ($row = mysqli_fetch_row($res)) [
$id = array_shift($row);
if (!isset($maxIterator))
$maxIterator = count($row)-1;
$current =& $result;
for ($i=0; $i<$maxIterator; $i++) {
if (empty($row[$i]))
break;
if (!array_key_exists($row[$i], $current))
$current[ $row[$i] ] = array();
$current =& $current[ $row[$i] ];
}
//for properly ended and wasn't broken out of sooner
if ($i == $maxIterator) {
if (!array_key_exists($row[$i], $current))
$current[ $row[$i] ] = 1;
else
$current[ $row[$i] ]++;
}
}
array_shift basically does, what you needed two lines for: get the first element of an array and then remove it. Then I save the result of the count in a variable, so it doesn't need to be recalculated in every iteration of the for AND while.
Also I would suggest setting $maxIterator manually. With the shown result a good default would be 5. This way all values before the 5th. will be used for nesting and the 5th itself will be used to count (in your example this is storage size).
As the for will execute $i++ after the last iteration (and then it fails the condition and hence the loop breaks), it can be used for the counting.
Personally I would overthink what exactly you are doing and maybe use a specifc structure for that. However, this code should give you a good impression how it can be solved using references.
This is what my array looks like :
Array (
[0] => SimpleXMLElement Object (
[key] => Array (
[0] => Track ID
[1] => Name
[2] => Artist
[3] => Album Artist
[4] => Composer
[5] => Album
[6] => Genre
[7] => Kind
[8] => Size
[9] => Total Time
[10] => Disc Number
[11] => Disc Count
[12] => Track Number
[13] => Year
[14] => Date Modified
[15] => Date Added
[16] => Bit Rate
[17] => Sample Rate
[18] => Play Count
[19] => Play Date
[20] => Play Date UTC
[21] => Artwork Count
[22] => Persistent ID
[23] => Track Type
[24] => Location
[25] => File Folder Count
[26] => Library Folder Count )
[integer] => Array (
[0] => 2056
[1] => 3732918
[2] => 230661
[3] => 1
[4] => 1
[5] => 1
[6] => 1993
[7] => 128
[8] => 44100
[9] => 3
[10] => 3439412487
[11] => 1
[12] => 5
[13] => 1 )
[string] => Array (
[0] => Eye of the Tiger
[1] => Survivor
[2] => Survivor
[3] => Frankie Sullivan/Jim Peterik
[4] => Greatest Hits
[5] => Rock
[6] => MPEG audio file
[7] => 772F0F53F195E705
[8] => File
[9] => file://localhost/Users/cameron/Music/iTunes/iTunes%20Media/Music/Survivor/Greatest%20Hits/01%20Eye%20of%20the%20Tiger.mp3 )
[date] => Array (
[0] => 2012-08-27T17:01:00Z
[1] => 2012-08-27T17:01:03Z
[2] => 2012-12-27T07:21:27Z ) )
that's 1 result, there is about 50 of them repeated.
I am trying to select the artist value in this case : Frankie Sullivan/Jim Peterik
please note: there is about 50 other results that come after this first one, so I would like to do a foreach to display all results.
any suggestions? I am stuck.this is the code I used to get these results:
$xml = simplexml_load_file('Library.xml');
$xmlx = $xml->dict->dict->dict->key;
$artist = $xmlx->xpath("//dict[key='Artist']");
echo "<pre>" . print_r($artist, true) . "</pre>";
It seems that you have an array of SimpleXMLElement,
so you can iterate over your array and use the SimpleXMLElement facilities.
Try:
foreach($yourArray as $simpleXmlElement)
{
// Retrieve the name
echo $simpleXmlElement->string[3];
}
Take a look at the documentation for more question: SimpleXMLElement
For your specific problem, assuming the key and string are synchronized, you can try:
// Loop on your array of SimpleXMLElement
foreach($yourArray as $simpleXmlElement)
{
// Initialize the position and found value
$position = 0;
$found = false;
// Loop on the sub array 'key' and search the 'Artist Album' position
foreach($simpleXmlElement->key as $index => $value)
{
if ($value == "Album Artist")
{
$found = true;
break;
}
// Not found, increment position
$position++;
}
// Retrieve the name if found the artist album key
if ($found)
echo $simpleXmlElement->string[$position];
}
As
[3] => Album Artist
will give the position 3
Then, when retrieving the string value, it will return Frankie Sullivan/Jim Peterik