PHP how to optimize writing to file in this situation - php

To better explain you my situation I will both describe it and supply corresponding pseudo-code(sort of). I'm in a dilemma and need some help.
So I have this function which is called upon consecutively and frequently. In the function I have a for loop which executes a variable number of times, based on supplied data. In that for loop there is an array which gets populated with all of that data. Still in the function, when the for loop ends, the array gets written into a CSV file. And then execution stops. However as I mentioned the function gets called frequently one call after the other, this results in repeated steps of populating the array in the loop and then writing into the file. The pseudocode illustrates this situation better(not my actual code, just mockup):
-call function stuff n times
//Paragraph2 solution? -- global array declaration here ?
function stuff
{
for loop(conditions)
{
array <= data
}
array => file // Paragraph2 solution? -- Global array <= loop arrays
}
// Paragraph2 solution? -- Global array => write to file
This works just fine. The problem lies in the speed of writing to the file. I think it is impaired because of all the little arrays that constantly get written into the file. I want to make all these arrays in the for loop to write their data into a global array outside the loop so that I can just take this one array with all the data and insert it in the CSV file, so I would have just one transaction to the file instead of the countless transactions that I had before. So, is this what I thought of possible, is it correct, or is there a better way of doing this? And can you please supply usable code in you answer. Thank You.

This is how you can use a global array inside the function
$stuff = array();
function add_stuff($new_stuff)
{
global $stuff;
$stuff[] = $new_stuff;
}
add_stuff("hello");
add_stuff("world");
print_r($stuff);
the output should be:
Array
(
[0] => hello
[1] => world
)

Related

PHP array_push() inside a function in a class to array outside of class

I'm struggling with my lack of operational knowledge with handling or arrays and variables within a private function that is within a class in an applciation I've "inherited" control of.
The function loops for X days, within that loop, a certain number of MySQL rows will be returned, from a range of different queries. Each row from each query issues a +1 to a counter.
Some maths is then performed on the value of the counter (not really relevant)
Once X days have been iterated through, I need to discard all days calcualted coutner value EXCEPT the value that was the highest. I had planned on using max($array); for this.
I will greatly strip down the code for the purpose of this example:
class Calendar {
public $heights;
private fucntion dayLoop($cellNumber) {
$heights = []; //array
$block_count = 0; //counter
while(mysqlrowdata) {
[code for mysql operations]
$block_count++; //increment the count
}
$day_height = ($block_count * 16) + 18; //do some math specific to my application
$this->heights[] = $day_height; //commit calc'd value to array
//array_push($heights, $day_height); //this was a previosu attempt, i dont think i should use array_push here..??
}
}
This function is called on other "front end" pages, and if I perform a var_dump($heights); at the bottom of one of those pages, the array returns empty with
Array ( )
Essentially, at that front end page, I need to be able to A) inspect the array with vlaues from each looped day from X days, and B) pull the largest calc'd counter value from any of the X days that were iterated through in the loop.
I have tried a myriad of things, like changing the function to be public, defining the start of the array on the front end pages instead of anywhere in the class or fucntion. I declared array name as a variabel in the class as I read that I needed to do that.
Overall, I just don't really understand how I'm MEANT to be handling this, or if I'm going about it in completely the wrong way? Solutions very welcome, but advice and words of wisdom also appreciated greatly. Thanks.

Can you get value from an array without getting the array first?

Bear with me, I'm learning.
I often see snippets like the one below:
<?p
$imageArray = get_field('image_field');
$imageAlt = $imageArray['alt'];
$imageURL = $imageArray['url'];
?>
It is pedagogical and clear and organized. But is it necessary to get the entire array before querying the array for values? Can I not define the variable in just a single line? Something like the below (which doesn't work, neither the other variants I have tried):
$imageAlt = get_field('image_field', ['alt']);
$imageURL = get_field('image_field', ['url']);
Yes, you can.
As of PHP 5.4 it is possible to array dereference the result of a function or method call directly. Before it was only possible using a temporary variable. - Source
$imageAlt = get_field('image_field')['alt'];
https://eval.in/548036
The question you are asking can be answered by asking 2 questions:
Is it doable ?
Is it a good idea to do it that way ?
Is it doable ?
Yes! You do not have to store the array in a variable and re-use it later.
For instance, you could do:
$imageAlt = get_field('image_field')['alt'];
Note: This will work in PHP 5.4+ and is called: Array dereferencing.
But that is not the only consideration...
Is it a good idea to do it that way ?
No. It's not a good idea in many cases. The get_field() function, depending on your context, is probably doing a lot of work and, each time you call it, the same work is don multiple times.
Let's say you use the count() function. It will count the number of items in an array. To do that, it must iterate through all items to get the value.
If you use the count() function each time you need to validate number of items in an array, you are doing the task of counting each and every time. If you have 10 items in your array, you probably won't notice. But if you have thousands of items in your array, this may cause a delay problem to compute your code (a.k.a. it will be slow).
That is why you would want to do something like: $count = count($myArray); and use a variable instead of calling the function.
The same applies to your question.
While PHP 5.4+ allows you to directly dereference a function return value like this:
get_field('image_field')['alt']
...in this particular case I would not suggest you do so, since you're using two values from the resulting array. A function call has a certain overhead just in itself, and additionally you don't know what the function does behind the scenes before it returns a result. If you call the function twice, you may incur a ton of unnecessary work, where a single function call would have done just as well.
This is not to mention keeping your code DRY; if you need to change the particulars of the function call, you now need to change it twice...
PHP allows you to play around quite a bit:
function foo(){
return array('foo' => 1, 'bar' => 2);
}
Option 1
echo foo()['foo']; // 1
# Better do this if you plan to reuse the array value.
echo ($tmp = foo())['foo']; // 1
echo $tmp['bar']; // 2
It is not recommended to call a function that returns an array, to specifically fetch 1 key and on the next line doing the same thing.
So it is better to store the result of the function in a variable so you can use it afterwards.
Option 2
list($foo, $bar) = array_values(foo());
#foo is the first element of the array, and sets in $foo.
#bar is the second element, and will be set in $bar.
#This behavior is in PHP 7, previously it was ordered from right to left.
echo $foo, $bar; // 12
Option 3
extract(foo()); // Creates variable from the array keys.
echo $foo, $bar;
extract(get_field('image_field'));
echo $alt, $url;
Find more information on the list constructor and extract function.

Insert into array during foreach

I'm fairly certain the answer is no, but is it possible to insert something into an array during a foreach loop? Ideally at the very spot you are at in the array during the loop.
For example:
foreach($stock->StockData as &$stock) {
if($dateTime < $stock['DateTime']) {
// INSERT NEW RECORD AT THIS SPOT IN THE ARRAY
}
}
As I say, I'm fairly certain the answer is no, but rather than build a new array, I just thought I'd ask.
I stand corrected!
http://docstore.mik.ua/orelly/webprog/php/ch05_07.htm
It apparently is just fine to do this in PHP.
According to the reference, PHP operates on a copy of the array when you start a foreach iterator, meaning that the iterator will not be corrupted by operations on the original array within the body of the foreach!
You really don't want to mutate an object is being iterated on. It will break your iterator/loop and could possibly crash the script/program by accessing or changing memory that you don't have access to anymore, possibly because array size has reduced.

array to variables

I'm programming in PHP and I have a huge array which contains a lot of ID's. I need all these ID's to be variables so I can use these in another function. I have done a lot of research on loops in PHP but I can find one which "converts" the arrays into variables that I can use in another function. So far I have a foreach loop which processes the whole array and divided into $persons. But when I use $persons in the next function it only uses the last array. My code is as follows:
$retrieved_id_array=explode(",",$retrieved_id_string);
foreach($retrieved_id_array as $persons)
$retrieved_string=file_get_contents("https://HDXLfansite.com/$persons");
So the problem is how do I make a loop which provides me with several variables I can use in another function? Or should I use another method/code?
thats because you are overwriting your variable $retrieved_string in loop, you could do:
foreach($retrieved_id_array as $persons) {
//add it in array
$retrieved_string[] =file_get_contents("https://HDXLfansite.com/$persons");
}

PHP scope question

I'm trying to look through an array of records (staff members), in this loop, I call a function which returns another array of records (appointments for each staff member).
foreach($staffmembers as $staffmember)
{
$staffmember['appointments'] = get_staffmember_appointments_for_day($staffmember);
// print_r($staffmember['appointments'] works fine
}
This is working OK, however, later on in the script, I need to loop through the records again, this time making use of the appointment arrays, however they are unavailable.
foreach ($staffmembers as $staffmember)
{
//do some other stuff
//print_r($staffmember['appointments'] no longer does anything
}
Normally, I would perform the function from the first loop, within the second, however this loop is already nested within two others, which would cause the same sql query to be run 168 times.
Can anyone suggest a workaround?
Any advice would be greatly appreciated.
Thanks
foreach iterates over a copy of the array. If you want to change the value, you need to reference it:
foreach($staffmembers as &$staffmember) // <-- note the &
{
$staffmember['appointments'] = get_staffmember_appointments_for_day($staffmember);
// print_r($staffmember['appointments'] works fine
}
From the documentation:
Note: Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. foreach has some side effects on the array pointer. Don't rely on the array pointer during or after the foreach without resetting it.
and
As of PHP 5, you can easily modify array's elements by preceding $value with &. This will assign reference instead of copying the value.

Categories