Reduce memory size of my PHP array - php

I've just come across the problem of the large memory size of PHP arrays. I'm trying to store a fairly small amount of data per object, in a bunch of small arrays. The storage looks like this.
[Stats] => Array
(
[Apps] => Array
(
[Career] => Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
)
[Team] => Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
)
[Season] => Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
)
)
[SubApps] => Array
(
[Career] => Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
)
[Team] => Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
)
[Season] => Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
)
)
I need 20 or more of the middle arrays shown here (e.g 'Apps', 'SubApps' etc). It's an array of arrays of arrays, with the final arrays always being exactly 6 values long.
Since it's just 18 values, I'd assumed that it wasn't much memory, but I've found out that PHP uses about 144 bytes per value, so it's turning out to be huge, especially since I have about 3000 such objects. It's using about 30k per object, just on 20 of these array blocks.
So I'm looking for a memory efficient solution. Since my final array is always 6 values, I'm thinking that maybe I can pack/unpack. I also looked into SplFixedArray but it doesn't suit my needs in some ways and doesn't save much memory. I also want the values to show in a readable format in my database in case I need to edit them manually in the db (one method I tried saved memory but the values were garbled in the db).
UPDATE - Solution. I found a simple solution to this. The arrays are JSON_encode'd for saving to the database. When I load them, they're decoded. Initially I was decoding the whole batch at once, hence the massive memory usage, but the simple solution was to keep them encoded until needed, then decode - process - encode. This way, only one is ever decoded into the array and the rest remain encoded, which appears to use very small amounts of memory.

Related

Make a multidimensional array of three array in PHP

I want to make a array of arrays.
Problem:
My final array will be like this:
Array(Array1, Array2, Array3);
and arrays will be
Array1=Array ( [0] => 0 [1] => 100 [2] => 100 [3] => 0 [4] => 0 [5] => 0 [6] => 0
Array2=Array ( [0] => 0 [1] => 100 [2] => 100 [3] => 60 [4] => 0 [5] => 30 [6] => 0
Array3=Array ( [0] => 50 [1] => 100 [2] => 100 [3] => 0 [4] => 0 [5] => 0 [6] => 40
So how can make the multidimensional array and how can I access data from this array. Help will be appreciated. Thanks
Unlike a statically typed language, there is no need to declare these up front which can be confusing to newcomers. Really what you're describing is just a two-dimensional array. So really you have two options. Assuming these aren't associative like your example above, either putting arrays together:
$array = array($array1, $array2, $array3);
Or if you are doing something with loops/iterators you can just define your two-d array on the fly:
$array[$itr][$inner_itr] = $array1[$inner_itr];
Hope that helps.

HTML input array name coming through as a string

I have an input checkbox field as follows:
<input type="checkbox" name="group_items[<?=$item_id?>][<?=$group_id?>]" value="1" />
There are several of these in a matrix grid. On submission, it should post something like this:
(array) Array
(
[1] => Array
(
[1] => 1
[3] => 1
[5] => 1
[9] => 1
[13] => 1
[15] => 1
)
[2] => Array
(
[1] => 1
[3] => 1
[5] => 1
[9] => 1
[13] => 1
[15] => 1
)
[3] => Array
(
[2] => 1
[4] => 1
[8] => 1
[10] => 1
[14] => 1
)
[4] => Array
(
[2] => 1
[4] => 1
[8] => 1
[10] => 1
[14] => 1
)
)
Most of the time, this seems to be okay.
I then run this:
if(!empty($_POST['group_items']))
{
foreach($_POST['group_items'] as $item_id => $item_groups)
{
$group_ids = array_keys($item_groups);
foreach($group_ids as $group_id)
{
// do something
}
}
}
However, on occassion, I get this error:
Uncaught PHP Error: array_keys() expects parameter 1 to be array, string given
It's as though it's posting this:
(array) Array
(
[1] => (string)
)
I am well aware that I can perform an is_array check on $item_groups, however I need to understand how this can even be a string instead of an array.
I am also aware that I could change the values from 1 to be what the key is currently set to, and have a zero-based index, like this:
(array) Array
(
[1] => Array
(
[0] => 1
[1] => 3
[2] => 5
[3] => 9
[4] => 13
[5] => 15
)
)
However this would not do anything to resolve the issue of the value of [1] being a string instead of an array.
I'm also unable to log out the post data as a client has lost data due to this error and logging the post to see what it contains would risk them losing more data. This is also why an is_array check is not the solution as it would mean the posted data has still somehow been lost and doesn't solve the actual cause.
I have checked the server limits for the maximum number of fields that can be posted and it is high enough; I can submit hundreds of checkboxes and they come through fine. This also seems to be an intermittent error and can work as expected deveral times, and then cause the error the next.
Does anybody have any suggestions on a cause?
Edit: Have now got a dump of the data when it errors.
(array) Array
(
[0] => 1
)

Fetching data from moodle database

I am trying to query some data from the moodle database. I am using the data manipulation API. Here is my code. When I run it on the browser, i get a blank screen. i reall dont know what the $enrolids is. Is it an associative array or what. Even when I try create an associative array, I still get a blank screen.
<?php
require_once("../config.php");
$userid=$_GET['userid'];
//Get the enrolids from the mdl_user_enrolments table
$enrolids=$DB->get_records_sql('SELECT enrolid FROM {user_enrolments} WHERE userid=?', array($userid));
echo $enrolids['enrolid'];
?>
Will appreciate the help....
I figured it out:
To anyone with the same problem. Here is the solution.
Moodle is object oriented. Meaning, the queries made, return an Array of stdclass objects i.e:
Array ( [1] => stdClass Object ( [id] => 1 [status] => 0 [enrolid] => 5 [userid] => 3 [timestart] => 0 [timeend] => 2147483647 [modifierid] => 0 [timecreated] => 0 [timemodified] => 0 ) [2] => stdClass Object ( [id] => 2 [status] => 0 [enrolid] => 6 [userid] => 3 [timestart] => 0 [timeend] => 2147483647 [modifierid] => 0 [timecreated] => 0 [timemodified] => 0 ) )
Use the -> notation to fetch whatever value you desire i.e If the above array is stored in a variable e.g. $arr, do the following to access status for example
$arr[1]->status;
CHEERS....

multi dimensional array in random order

I want to make it so that my multi dimensional array is in a random order. How would you do it?
// This is how the array looks like
print_r($slides);
Array
(
[0] => Array
(
[id] => 7
[status] => 1
[sortorder] => 0
[title] => Pants
)
[1] => Array
(
[id] => 8
[status] => 1
[sortorder] => 0
[title] => Jewels
)
[2] => Array
(
[id] => 9
[status] => 1
[sortorder] => 0
[title] => Birdhouse
)
[3] => Array
(
[id] => 10
[status] => 1
[sortorder] => 0
[title] => Shirt
)
[4] => Array
(
[id] => 11
[status] => 1
[sortorder] => 0
[title] => Phone
)
)
// This how the result is if I use array_rand()
print_r(array_rand($slides, 5));
Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[4] => 4
)
// This how the result is if I use shuffle()
print_r(shuffle($slides));
1
shuffle() is the way to go here. It prints 1 because shuffle changes the array in-place and returns a boolean, as it is written in the documentation:
Returns TRUE on success or FALSE on failure.
I suggest to also read the documentation of array_rand():
Picks one or more random entries out of an array, and returns the key (or keys) of the random entries.
Always read documentation if you use built-in functions. Don't just assume how the work. I bet it took more time to write the question than looking this up.
Instead of
print_r(shuffle($slides));
do
shuffle($slides);
print_r($slides);
You see shuffle() shuffles the array in-place
i am not sure how you want it to display but you can loop the array and use php rand(0,arraylen) function to parse the array.
It works perfect. print_r(shuffle($slides))) gives the output of TRUE, since the return value of shuffle is a boolean and not an array.
See the working example here: http://codepad.org/B5SlcjGf

Grouping data in array

I want to group data in PHP like so:
I have an array with dumped stuff in it
Array (
[0] => Array (
[0] => 123
[1] => 3000
[2] => 595
[3] => 1005
)
[1] => Array (
[0] => 53
[1] => 700
[2] => 195
[3] => 315
)
[2] => Array (
[0] => 82
[1] => 142
[2] => 342
[3] => 640
)
[3] => Array (
[0] => 82
[1] => 702
[2] => 200
[3] => 320
)
)
This array represents items in 3D. What I want to achieve is to group them by coordinates so that if (roughly) they are close together (let's say closer than 10 units on each axis).
So far I came up with following script: http://pastebin.com/wJ5HpTPL however it seems be failing - it groups some records for no reason at all and don't group those that I want. And I know how inefficient it is however I tried several methods that was failing and it evolved into that crappy code.
There is about 2000 of items however the script is going to be run for administrative purposes and is hosted on my local server so performance is not important.
To calculate the difference you can use Pythagoras' theorem and:
It's explained really well here: http://betterexplained.com/articles/measure-any-distance-with-the-pythagorean-theorem/
I have resolved my problem by simply using $row = $bulk[$i]; in my code instead of $row = next($bulk); which for some reason was causing problems.

Categories