Categories
makitweb.com

Upload all files on button click – Dropzone and PHP

Dropzone auto uploads the selected file or drag file to the server.

Sometimes, it requires to upload all selected files on a single click instead of uploading it instantly.

With Dropzone options and method this can easily be implemented.

In this tutorial, I show how you upload all selected files in the Dropzone area on a button click.

Upload all files on button click – Dropzone and PHP

Categories
alexwebdevelop.com

How to check how much memory your PHP scripts use: a tutorial with examples

[et_pb_section fb_built=”1″ module_class=”underline_links” _builder_version=”3.22″][et_pb_row _builder_version=”3.25″ background_size=”initial” background_position=”top_left” background_repeat=”repeat” custom_padding=”27px|0px|27px|0px”][et_pb_column type=”4_4″ _builder_version=”3.25″ custom_padding=”|||” custom_padding__hover=”|||”][et_pb_text ul_position=”inside” _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”1.9em” ul_font=”||||||||” ul_font_size=”17px” ul_line_height=”2em” ol_font=”||||||||” background_size=”initial” background_position=”top_left” background_repeat=”repeat”]

How much memory does your PHP script use?

Memory efficiency is not among the first things to learn about PHP, but checking how much memory a PHP script is using can be very useful.

Learning about memory and code optimization is also among the steps I recommend in my free guide to become a better PHP developer.

 

Keep reading to learn how to check your PHP scripts memory usage and to see some specific examples.

 

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#222222″ text_font_size=”15px” link_font=”||||||||” link_font_size=”14px” ul_font=”||||||||” ul_font_size=”16px” ul_line_height=”1.7em” ol_font=”||||||||” ol_font_size=”15px” ol_line_height=”1.8em” header_font=”||||||||” header_3_font=”||||||||” header_3_font_size=”20px”]

Table of contents

  1. Why you should check your scripts memory usage
  2. memory_get_usage() and memory_get_peak_usage()
  3. The $real_usage argument: how to use it
  4. How to monitor loops
  5. How to monitor PHP daemons
  6. How to get email notifications when too much memory is used
  7. A caveat: PHP resources (don’t miss this)
  8. Conclusion

 

[/et_pb_text][et_pb_text disabled_on=”on|off|off” _builder_version=”3.27.4″]

 

[/et_pb_text][et_pb_image src=”https://alexwebdevelop.com/wp-content/uploads/2018/06/php-script-memory-usage.jpg” alt=”PHP memory usage” title_text=”PHP memory usage” align=”center” align_tablet=”center” align_last_edited=”on|desktop” _builder_version=”3.23″ custom_margin=”||5px|” custom_padding=”|||”][/et_pb_image][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#666666″ text_font_size=”12px” link_font=”||||||||” link_font_size=”11px” text_orientation=”center” custom_margin=”|||” custom_padding=”|||”]Designed by Freepik[/et_pb_text][/et_pb_column][/et_pb_row][et_pb_row _builder_version=”3.25″ background_size=”initial” background_position=”top_left” background_repeat=”repeat” custom_padding=”27px|0px|27px|0|false|false”][et_pb_column type=”4_4″ _builder_version=”3.25″ custom_padding=”|||” custom_padding__hover=”|||”][et_pb_text disabled_on=”on|off|off” _builder_version=”3.27.4″]

 

[/et_pb_text][et_pb_text module_id=”scripts-memory-usage” _builder_version=”3.27.4″ header_font=”||||||||” header_2_font=”||||||||” header_2_text_color=”#26282d” header_2_line_height=”1.4em”]

 

WHY YOU SHOULD CHECK YOUR SCRIPTS MEMORY USAGE

[/et_pb_text][et_pb_blurb use_icon=”on” font_icon=”%%52%%” icon_color=”#0c71c3″ _builder_version=”3.21.4″ animation=”off”][/et_pb_blurb][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”1.9em” ul_font=”||||||||” ul_font_size=”16px” ul_line_height=”1.7em” custom_margin=”||0px|” custom_padding=”|||”]

Among web applications requirements, memory efficiency is not usually at the top of the list.

And, generally speaking, that’s fine.

Other factors, like SQL security and authentication good practices, are surely more important.

 

However, excessive memory consumption can be a real problem.

In fact, memory consumption issues can easily lead to crashes, hard-to-find bugs and even open the door to Denial-of-Service attacks.

This is especially important in high traffic websites, where many concurrent script executions occur and it’s easier for memory-related issues to cause problems.

 

Before moving to the next part, I suggest you look at the following short video, which explains nicely how memory management works in PHP and gives you some basics tips to optimize your code:

 

[/et_pb_text][et_pb_video src=”https://www.youtube.com/watch?v=l6lq_RJtozA” _builder_version=”3.19.4″][/et_pb_video][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”1.9em” ul_font=”||||||||” ul_text_color=”#26282d” ul_font_size=”17px” ul_line_height=”1.9em” custom_margin=”||0px|” custom_padding=”|||”]

 

 

Some kinds of PHP scripts are particularly at risk of excessive memory consumption:

  • very complex scripts, especially if including nested loops;
  • scripts using external resources like XML files, database result sets and remote connections;
  • always-on scripts like PHP daemons.

Of course, memory issues can occur in other kinds of script as well.

 

But how can you check how much memory your script is using?

It’s easy:

the standard PHP library provides you with two functions that give you that exact information: memory_get_usage() and memory_get_peak_usage().

Let’s see how they work. 

[/et_pb_text][et_pb_code _builder_version=”3.18.7″] [easy-tweet tweet=”A tutorial (with examples) on how to check your PHP script memory usage” via=”no” hashtags=”PHP”]  [/et_pb_code][et_pb_text module_id=”functions” _builder_version=”3.27.4″ header_font=”||||||||” header_2_font=”||||||||” header_2_text_color=”#26282d”]

  

memory_get_usage() AND memory_get_peak_usage()

[/et_pb_text][et_pb_blurb use_icon=”on” font_icon=”%%176%%” icon_color=”#25c90c” _builder_version=”3.21.4″ animation=”off”][/et_pb_blurb][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”1.9em” ul_font=”||||||||” ul_font_size=”17px” ul_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

 

memory_get_usage() returns the number of bytes used by the script when the function is called.

Similarly, memory_get_peak_usage() returns the maximum amount of memory (again, in bytes) used by the script until the function is called.

For example:

 

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”13px”]

<?php

$big_array = array();

for ($i = 0; $i < 1000000; $i++)
{
   $big_array[] = $i;
}

echo 'After building the array.<br>';
print_mem();

unset($big_array);

echo 'After unsetting the array.<br>';
print_mem();


function print_mem()
{
   /* Currently used memory */
   $mem_usage = memory_get_usage();
   
   /* Peak memory usage */
   $mem_peak = memory_get_peak_usage();

   echo 'The script is now using: <strong>' . round($mem_usage / 1024) . 'KB</strong> of memory.<br>';
   echo 'Peak usage: <strong>' . round($mem_peak / 1024) . 'KB</strong> of memory.<br><br>';
}

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”2em” ul_font=”||||||||” ul_font_size=”17px” ul_line_height=”2em” ol_font=”||||||||” ol_font_size=”17px” ol_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

 

On my PC, I get:

 

[/et_pb_text][et_pb_image src=”https://alexwebdevelop.com/wp-content/uploads/2019/01/mem-usage.png” alt=”Memory usage output” title_text=”Memory usage output” align=”center” align_tablet=”center” align_last_edited=”on|desktop” _builder_version=”3.23″][/et_pb_image][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”1.9em” ul_font=”||||||||” ul_font_size=”17px” ul_line_height=”2em” ol_font=”||||||||” ol_font_size=”17px” ol_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

 

As you see, after the array is unset the current memory usage goes down to 370Kb, but the peak usage remains the same.

(If you want to learn how to set up a local PHP environment, see the Getting started chapter of my PHP learning program).

Both functions take an optional boolean argument named $real_usage. Its default value is false.

What’s it’s meaning and when should you set it to true?

Let’s find out.

[/et_pb_text][et_pb_blurb use_icon=”on” font_icon=”%%291%%” icon_color=”#0c71c3″ icon_placement=”left” content_max_width=”720px” use_icon_font_size=”on” icon_font_size=”48px” content_max_width_last_edited=”off|desktop” icon_font_size_last_edited=”off|desktop” _builder_version=”3.21.4″ body_font=”||||||||” body_text_color=”#0c71c3″ custom_margin=”64px||” custom_margin_tablet=”” custom_margin_phone=”” custom_margin_last_edited=”on|desktop” animation=”off”]

Would you like to talk with me and other developers about PHP and web development? Join my Facebook Group: Alex PHP café

See you there 🙂

[/et_pb_blurb][et_pb_text module_id=”real-usage” _builder_version=”3.27.4″ header_font=”||||||||” header_2_font=”||||||||” header_2_text_color=”#26282d”]

 

 

THE $real_usage ARGUMENT: HOW TO USE IT

[/et_pb_text][et_pb_blurb use_icon=”on” font_icon=”%%57%%” icon_color=”#e02b20″ use_icon_font_size=”on” icon_font_size=”72px” _builder_version=”3.21.4″ animation=”off”][/et_pb_blurb][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”1.9em” ul_font=”||||||||” ul_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

$real_usage is a boolean argument. Its default value is false for both memory_get_usage() and memory_get_peak_usage().

If this argument is set to true, then the function returns the full amount of memory allocated by the PHP interpreter for the script instead of the memory actually used by the script.

What’s the difference…?

 

[/et_pb_text][et_pb_image src=”https://media.giphy.com/media/bPTXcJiIzzWz6/giphy.gif” align_tablet=”center” align_last_edited=”on|desktop” _builder_version=”3.23″][/et_pb_image][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”1.9em” ul_font=”||||||||” ul_line_height=”1.9em” custom_margin=”||0px|” custom_padding=”|||”]

 

This is how it works:

The PHP interpreter dynamically allocates memory for the script. This memory is allocated in chunks, small pieces of a fixed amount of memory.

When all the allocated memory has been used by the script, the interpreter allocates another chunk.

So:

  • first, the interpreter reserves a chunk of memory for the script to use;
  • then the script gradually fills it with its data, until the chunk is full;
  • if the script needs more memory, the interpreter allocates another chunk of memory;
  • repeat…

 

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”1.9em” ul_font=”||||||||” ul_line_height=”1.9em” custom_margin=”||0px|” custom_padding=”|||”]

Therefore, the amount of allocated memory is always a bit bigger than the amount of used memory (how much bigger depends on many factors, including the PHP configuration and the operating system settings).

 

This is what $real_usage is used for:

  • If $real_usage is set to false (the default), then the functions return the used memory only.
  • If $real_usage is set to true, then the functions return the whole allocated memory.

 

The following example shows how the allocated memory grows along with the memory actually used by the script:

 

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”13px”]

<table align="center" valign="top">
<tr>
<td>Used memory</td>
<td>Allocated memory</td>
<td>Difference</td>
</tr>

<?php

$big_array = array();

for ($i = 0; $i < 100000; $i++)
{
   $big_array[] = 'aaa' . $i;
   
   if (($i % 7000) == 0)
   {
      /* With $real_usage = false (the default value) */
      $used_mem = round(memory_get_usage(false) / 1024);
      
      /* With $real_usage = true */
      $alloc_mem = round(memory_get_usage(true) / 1024);
      
      echo '<tr><td style="color: green; border: 1px solid #888;">' . $used_mem . 'KB</td>';
      echo '<td style="color: blue; border: 1px solid #888;">' . $alloc_mem . 'KB</td>';
      echo '<td style="color: red; border: 1px solid #888;">' . ($alloc_mem - $used_mem) . 'KB</td></tr>';
   }
}

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

 

This is the result:

[/et_pb_text][et_pb_image src=”https://alexwebdevelop.com/wp-content/uploads/2019/01/memory-real-usage.png” alt=”PHP memory real usage” title_text=”PHP memory real usage” align=”center” align_tablet=”center” align_last_edited=”on|desktop” _builder_version=”3.23″ max_width=”80%” module_alignment=”center”][/et_pb_image][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

 

Notice how the used memory (the first column) grows gradually, while the allocated memory (the second column) grows in chunks.

 

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#222222″ text_font_size=”15px” text_line_height=”2em” link_font=”||||||||” link_font_size=”17px” link_line_height=”2em” custom_margin=”||0px|” custom_padding=”10px|15px|10px|15px|true|true” border_width_all=”1px” border_color_all=”#e09900″]

Note:

if you try running this example and get strange results, like the allocated memory being smaller than the used memory, it’s probably because of some caching system.

A way to avoid such problems is to restart the web server right before running the script.

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”1.9em” header_font=”||||||||” header_3_font=”||||||||” header_3_text_color=”#26282d” custom_margin=”||0px|” custom_padding=”|||”]

 

When should you set $real_usage to true?

 

Here is the rule of thumb:

if you want to see how much system memory your script is using, then you should set $real_usage to true.

Why?

Because the allocated memory, even if it’s not actually used by the script, is still reserved for it and isn’t available for other system processes.

In other words, it is the amount of system RAM reserved for the PHP process.

 

On the other hand, if you want to profile your PHP script, then it’s better to leave it to false because you will see the memory usage in more detail.

In fact, that way you can see how much memory a specific piece of code is using regardless of how much memory is available to the script as a whole.

 

Let’s see a couple of examples of how to do this. 

 

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”15px” text_orientation=”center”]I hope you are enjoying this guide! Why don’t you share it with your friends?
It’s just 1 second of your time and you’ll make me happy 🙂
[/et_pb_text][et_pb_code _builder_version=”3.19.4″ text_orientation=”center”]

[/et_pb_code][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#222222″ text_font_size=”17px” text_line_height=”2em” link_font=”||||||||” link_font_size=”17px” link_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”][/et_pb_text][et_pb_text module_id=”loops” _builder_version=”3.27.4″ header_font=”||||||||” header_2_font=”||||||||” header_2_text_color=”#26282d” custom_margin=”||0px|” custom_padding=”|||”]

 

 

HOW TO MONITOR LOOPS

[/et_pb_text][et_pb_blurb use_icon=”on” font_icon=”%%135%%” icon_color=”#e09900″ use_icon_font_size=”on” icon_font_size=”72px” _builder_version=”3.18.7″ animation=”off”][/et_pb_blurb][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”1.9em” ul_font=”||||||||” ul_font_size=”17px” ul_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

Inside loop structures excessive memory usage can lead to problems, especially if this usage keeps growing after each loop iteration.

If you want to make sure a loop isn’t using too much memory, it’s a good idea to profile it.

How can you do it?

 

To begin with, you should print the memory usage before and after the loop to check the difference.

If you see that the memory usage is too high, then you should also check inside the loop itself.

The $real_usage parameter is better left to false, because you want to profile your code in detail more than your whole script.

 

It’s also useful to see how much of the maximum available memory is being used.

A PHP script can use only up to a certain amount of memory. This value is set in the memory_limit variable of the php.ini file (the main PHP configuration file).

You can retrieve that value with the ini_get() function, convert it into bytes and compare it to the script’s memory usage.

 

Here’s an example:

 

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”13px”]

<?php

$mem_usage = memory_get_usage();
echo 'Memory usage before the loop: <strong>' . round($mem_usage / 1024) . 'KB</strong><br>';

/* Get the memory limit in bytes. */
$mem_limit = get_memory_limit();
echo 'Memory limit: <strong>' . round($mem_limit / 1048576) . 'MB</strong><br>';

$array = array();

for ($i = 0; $i < 100000; $i++)
{
   $array[] = $i;
   
   /* Check the memory usage every 10000 iterations. */
   if (($i % 10000) == 0)
   {
     $mem_usage = memory_get_usage();
     $limit_perc = $mem_usage * 100 / $mem_limit;
     
     echo 'Memory usage after iteration ' . $i . ': <strong>' . round($mem_usage / 1024) . 'KB</strong> ';
     echo '(' . round($limit_perc) . '% of the available memory for the script)<br>';
   }
}

$mem_usage = memory_get_usage();
echo 'Memory usage after the loop: <strong>' . round($mem_usage / 1024) . 'KB</strong><br>';


/* Parse the memory_limit variable from the php.ini file. */
function get_memory_limit()
{
   $limit_string = ini_get('memory_limit');
   $unit = strtolower(mb_substr($limit_string, -1 ));
   $bytes = intval(mb_substr($limit_string, 0, -1), 10);
   
   switch ($unit)
   {
      case 'k':
         $bytes *= 1024;
         break 1;
      
      case 'm':
         $bytes *= 1048576;
         break 1;
      
      case 'g':
         $bytes *= 1073741824;
         break 1;
      
      default:
         break 1;
   }
   
   return $bytes;
}

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”17px” text_line_height=”2em” link_font=”||||||||” link_font_size=”17px” link_line_height=”2em” ul_font=”||||||||” ul_font_size=”17px” ul_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

 

[/et_pb_text][/et_pb_column][/et_pb_row][et_pb_row _builder_version=”3.25″ custom_padding=”27px|0px|27px|0px”][et_pb_column type=”4_4″ _builder_version=”3.25″ custom_padding=”|||” custom_padding__hover=”|||”][et_pb_text module_id=”daemons” _builder_version=”3.27.4″ header_font=”||||||||” header_2_font=”||||||||” header_2_text_color=”#26282d” custom_margin=”||0px|” custom_padding=”|||”]

  

HOW TO MONITOR PHP DAEMONS

[/et_pb_text][et_pb_blurb use_icon=”on” font_icon=”%%138%%” icon_color=”#8300e9″ use_icon_font_size=”on” icon_font_size=”72px” _builder_version=”3.18.7″ animation=”off”][/et_pb_blurb][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”1.9em” ul_font=”||||||||” ul_font_size=”17px” ul_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

 

PHP daemons are never-ending, looping scripts.

They are extremely useful for maintenance and monitoring tasks, like automatic email notification systems and maintenance operations.

Just like any always-on application, PHP daemons too can suffer from memory leaks.

A good practice is to check the memory usage at the beginning of each loop and do something if it turns out to be excessively high.

 

[/et_pb_text][et_pb_code _builder_version=”3.19.4″] [easy-tweet tweet=”Follow this tutorial to find out your PHP script memory usage” via=”no” hashtags=”PHP”]  [/et_pb_code][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”1.9em” ul_font=”||||||||” ul_font_size=”17px” ul_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

For example, you can kill or pause the daemon and send a notification email (you will see how to do it in the next chapter).

For this purpose, it’s better to set $real_usage to true, because you are now more interested in how much memory is really been used more than in profiling your script.

 

Of course, should memory issues occur, you will need to carefully profile the script to see where the problem comes from (for that, it will be better to leave $real_usage to false).

 

As an example, let’s see how to terminate a daemon if the used memory is more than 50Mb:

 

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”13px”]

<?php

/* Remove the execution time limit */
set_time_limit(0);

/* Iteration interval in seconds */
$sleep_time = 30;

/* Memory limit (50Mb) */
$mem_limit = 52428800;

$array = array();
$iteration = 0;

while (TRUE)
{
   $iteration++;
   
   /* Memory check */
   if (memory_get_usage(true) >= $mem_limit)
   {
      echo 'Memory limit exceeded after iteration ' . strval($iteration);
      die();
   }
   
   /* Sleep for the iteration interval */
   sleep($sleep_time);
   
   for ($i = 0; $i < 500000; $i++)
   {
      $array[] = $i;
   }
}

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_text_color=”#26282d” text_font_size=”17px” text_line_height=”1.9em” link_font=”||||||||” link_font_size=”17px” link_line_height=”1.9em” ul_font=”||||||||” ul_font_size=”17px” ul_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

 

You can also stop the daemon when its memory usage goes beyond certain percentage of the maximum allowed usage.

To do this, you need to compare the memory usage to the memory_limit value, just as you saw in the loop example before.

Here’s the example:

 

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”13px”]

<?php

/* Remove the execution time limit. */
set_time_limit(0);

/* Get the memory limit in bytes. */
$mem_limit = get_memory_limit();

/* Iteration interval in seconds. */
$sleep_time = 5;

/* Max memory usage: 10% of the memory_limit. */
$mem_perc_limit = 20;

$array = array();
$iteration = 0;

while (TRUE)
{
   $iteration++;
   
   /* Memory check. */
   $mem_usage = memory_get_usage(true);
   $perc_usage = $mem_usage * 100 / $mem_limit;
   
   if ($perc_usage >= $mem_perc_limit)
   {
      echo 'Memory limit exceeded after iteration ' . $iteration . ' (' . round($perc_usage) . '%)';
      die();
   }
   
   /* Sleep for the iteration interval */
   sleep($sleep_time);
   
   for ($i = 0; $i < 500000; $i++)
   {
      $array[] = $i;
   }
}


/* Parse the memory_limit variable from the php.ini file. */
function get_memory_limit()
{
   $limit_string = ini_get('memory_limit');
   $unit = strtolower(mb_substr($limit_string, -1 ));
   $bytes = intval(mb_substr($limit_string, 0, -1), 10);
   
   switch ($unit)
   {
      case 'k':
         $bytes *= 1024;
         break 1;
      
      case 'm':
         $bytes *= 1048576;
         break 1;
      
      case 'g':
         $bytes *= 1073741824;
         break 1;
      
      default:
         break 1;
   }
   
   return $bytes;
}

[/et_pb_text][et_pb_text module_id=”email-notifications” _builder_version=”3.27.4″ header_font=”||||||||” header_2_font=”||||||||” header_2_line_height=”1.4em” custom_margin=”||0px|” custom_padding=”|||”]

 

 

 

HOT TO GET EMAIL NOTIFICATIONS WHEN TOO MUCH MEMORY IS USED

[/et_pb_text][et_pb_blurb use_icon=”on” font_icon=”%%109%%” icon_color=”#0c71c3″ use_icon_font_size=”on” icon_font_size=”72px” _builder_version=”3.18.7″ animation=”off”][/et_pb_blurb][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”17px” text_line_height=”2em” link_font=”||||||||” link_font_size=”17px” link_line_height=”2em” ul_font=”||||||||” ul_font_size=”17px” ul_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

 

Sometimes, debugging and profiling a PHP script’s memory usage can be difficult.

It’s not always easy to retrieve the output from memory_get_usage() and memory_get_peak_usage(), especially when the memory usage depends on the request string values and other factors.

 

In some cases, memory issues may arise only under specific circumstances or only after some time (especially in PHP daemons).

Just echoing the memory usage isn’t always good enough.

You can’t just stare at your screen waiting for a memory leak to happen, right?

 

[/et_pb_text][et_pb_image src=”https://media.giphy.com/media/ZXKZWB13D6gFO/giphy.gif” align=”center” align_tablet=”center” align_last_edited=”on|desktop” _builder_version=”3.23″][/et_pb_image][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”17px” text_line_height=”2em” link_font=”||||||||” link_font_size=”17px” link_line_height=”2em” ul_font=”||||||||” ul_font_size=”17px” ul_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

 

 One solution is to log the memory usage information to a log file or a database.

But this solution isn’t perfect either, because you will end up with tons of logs that you need to read and manage.

 

A smarter solution is to make PHP do the hard work.

Instead of printing or logging everything, just check whether the memory usage is too high.

If not, continue the script execution. Otherwise, send yourself a notification email together with useful debugging information.

 

This simple procedure removes the need for you to actively check your scripts.

In fact, the scripts themselves will tell you when there’s something wrong 😉

Much better, isn’t it?

 

So, how can this be done in practice?

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”17px” text_line_height=”2em” link_font=”||||||||” link_font_size=”17px” link_line_height=”2em” ul_font=”||||||||” ul_font_size=”17px” ul_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

 

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”17px” text_line_height=”2em” link_font=”||||||||” link_font_size=”17px” link_line_height=”2em” ul_font=”||||||||” ul_font_size=”17px” ul_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

Let’s go back at the daemon example.

Now, before killing the script when the memory usage is too high, we send an email so that we know that this script has been terminated.

We also attach a file with the debug back trace and one with all the defined variables to make easier for us to debug the issue.

 

NOTE: you need to install PHPMailer first. Follow my PHPMailer tutorial to learn how to do it.

 

Here’s the code:

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”13px”]

<?php

/* PHPMailer */
use PHPMailerPHPMailerPHPMailer;
use PHPMailerPHPMailerException;
require 'C:xampphtdocsPHPMailer-mastersrcException.php';
require 'C:xampphtdocsPHPMailer-mastersrcPHPMailer.php';
require 'C:xampphtdocsPHPMailer-mastersrcSMTP.php';

/* Remove the execution time limit */
set_time_limit(0);

/* Iteration interval in seconds */
$sleep_time = 1;

/* Memory limit (50Mb) */
$mem_limit = 52428800;

$array = array();
$iteration = 0;

while (TRUE)
{
   $iteration++;
   
   /* Memory check */
   if (memory_get_usage(true) >= $mem_limit)
   {
      send_debug_email();
     echo 'This PHP script has been killed for using too much memory. An email has been sent.';
      die();
   }
   
   /* Sleep for the iteration interval */
   sleep($sleep_time);
   
   for ($i = 0; $i < 500000; $i++)
   {
      $array[] = $i;
   }
}

function send_debug_email()
{
   $mail = new PHPMailer(true);

   try {
      
     /* Source address */
      $mail->setFrom('php@mysite');
      
      /* Destination address */
      $mail->addAddress('my_address@mysite');
      
      /* Subject */
      $mail->Subject = 'PHP script memory error';
      
      /* Message */
      $mail->Body = 'This PHP script has been killed for using too much memory.';
      
      /* Add debug info as attachment */
      $mail->addStringAttachment(print_r(debug_backtrace(), true), 'debug_backtrace.txt');
      $mail->addStringAttachment(print_r(get_defined_vars(), true), 'defined_vars.txt');
      
      /* Use SMTP. */
      $mail->isSMTP();
      
      /* SMTP server adrress. */
      $mail->Host = 'mysmtp_server';

      /* Use SMTP authentication. */
      $mail->SMTPAuth = TRUE;
      
      /* Set the encryption system. */
      $mail->SMTPSecure = 'tls';
      
      /* SMTP authentication username. */
      $mail->Username = 'smtp@mysite';
      
      /* SMTP authentication password. */
      $mail->Password = 'smtp_passwd';
      
      /* Set the SMTP port. */
      $mail->Port = 587;

      /* Send the mail. */
      $mail->send();
   }
   catch (Exception $e)
   {
      echo $e->errorMessage();
   }
   catch (Exception $e)
   {
      echo $e->getMessage();
   }
}

[/et_pb_text][et_pb_text module_id=”resources” _builder_version=”3.27.4″ custom_margin=”||0px|” custom_padding=”|||”]

 

 

A CAVEAT: RESOURCES

[/et_pb_text][et_pb_blurb use_icon=”on” font_icon=”%%365%%” icon_color=”#10a08d” use_icon_font_size=”on” icon_font_size=”72px” _builder_version=”3.19.4″ animation=”off”][/et_pb_blurb][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”17px” text_line_height=”2em” link_font=”||||||||” link_font_size=”17px” link_line_height=”2em” ul_font=”||||||||” ul_font_size=”17px” ul_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

There is one problem with memory_get_usage() and memory_get_peak_usage():

they do NOT take resources into account.

PHP resource types include variables handled by external libraries or by the operating system, including:

The system memory for these types is not handled by the PHP core engine itself.

It’s the external library that does that.

Therefore, memory_get_[peak]_usage() does not include it in its result and you need to retrieve it in some other way.

 

This post from drib tech clearly explains this situation and also provides a solution:

Get the real amount of memory allocated by the PHP

 

The solution you find in the above post works on Linux systems only.

But don’t worry:

if you are using Windows, you can use the following code that relies on the tasklist windows tool:

 

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”13px”]

<?php

/* Load a big XML file to see the memory usage difference */
$xml_file = 'C:xampphtdocsbig_xml_file.xml';
$xml = simplexml_load_file($xml_file);

if ($xml === false)
{
   die('Unable to load and parse the XML file: "' . $xml_file . '"');
}

/* Tasklist command to get info about the process ID running this script */
$cmd = 'tasklist /fi "pid eq ' . strval(getmypid()) . '"';

/* Get the output from tasklist */
$tasklist = trim(exec($cmd, $output));

/* Parse the output to get the memory usage value */
$mem_val = mb_strrchr($tasklist, ' ', TRUE);
$mem_val = trim(mb_strrchr($mem_val, ' ', FALSE));
$mem_val = str_replace('.', '', $mem_val);

echo 'Memory usage from <em>memory_get_usage()</em>: ' . round(memory_get_usage(true) / 1024) . 'KB<br>';
echo 'Memory usage from <em>tasklist</em>: ' . $mem_val . 'KB<br>';

[/et_pb_text][et_pb_text module_id=”conclusion” _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”17px” text_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

 

 

CONCLUSION

 

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ text_font=”||||||||” text_font_size=”17px” text_line_height=”2em” link_font=”||||||||” link_font_size=”17px” link_line_height=”2em” custom_margin=”||0px|” custom_padding=”|||”]

Now you know why it’s important to keep your scripts memory usage under control, and you know how to do it.

You learned the difference between memory_get_usage() and memory_get_peak_usage() and what the $real_usage argument really means.

You also saw how to include external resource types in the calculation, on both Linux and Windows systems.

 

Now I’m curious:

how much memory is the last PHP script you wrote using?

Go check it and tell me in the comments below!

[/et_pb_text][et_pb_text _builder_version=”3.27.4″ custom_margin=”|||”]

 

If this tutorial has been helpful to you, please spend a second of your time to share it… thanks!

[/et_pb_text][et_pb_text _builder_version=”3.27.4″]

 

Alex

[/et_pb_text][et_pb_code][/et_pb_code][/et_pb_column][/et_pb_row][/et_pb_section]

Categories
makitweb.com

Datatable AJAX pagination with PHP and PDO

With Datatable you can easily implement pagination on the webpage in less time.

It gives all necessary features which require in the pagination like – searching, sorting, change the number of records display.

You only need to manage the AJAX file.

In this tutorial, I show how you can add Datatable pagination with PHP and PDO.

Datatable AJAX pagination with PHP and PDO