Solved

PHP > Setting server-wide variables?

Posted on 2009-04-15
8
296 Views
Last Modified: 2012-05-06
I have a PHP web page that Internet users access.  I have a second PHP script running as a system script under the root user.  I need to be able to communicate small bits of information from the Apache script to the system script so my options are:

1. Write the info to a file on disk.
2. Write the info to MySQL
3. Write the info to memory

Options 1 and 2 are bad because they take a lot of overhead in spinning disks, etc.  

So is there a simple way to do Option #3?  Like can I write the info to a new environment variable which would be available across the whole server like:

$_ENV['php_shared_data'][]='foo';
0
Comment
Question by:Geoff Millikan
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
8 Comments
 
LVL 11

Expert Comment

by:NoiS
ID: 24150415
PHP have shared memory function (shmop) But I never use it before.

I can suggest this piece of code but don't know if will work.


// Create 100 byte shared memory block with system id if 0xff3
$shm_id = shmop_open(0xff3, "c", 0644, 100);
if(!$shm_id) {
    echo "Couldn't create shared memory segment\n";
}
 
// Get shared memory block's size
$shm_size = shmop_size($shm_id);
echo "SHM Block Size: ".$shm_size. " has been created.\n";
 
// Lets write a test string into shared memory
$shm_bytes_written = shmop_write($shm_id, "my shared memory block", 0);
if($shm_bytes_written != strlen("my shared memory block")) {
    echo "Couldn't write the entire length of data\n";
}
 
// Now lets read the string back
$my_string = shmop_read($shm_id, 0, $shm_size);
if(!$my_string) {
    echo "Couldn't read from shared memory block\n";
}
echo "The data inside shared memory was: ".$my_string."\n";
 
//Now lets delete the block and close the shared memory segment
if(!shmop_delete($shm_id)) {
    echo "Couldn't mark shared memory block for deletion.";
}
shmop_close($shm_id);

Open in new window

0
 

Author Comment

by:Geoff Millikan
ID: 24150520
The shmop() function doesn't appear to persist.  The tests I did showed that once the Apache script is done running it seems that whatever was put into memory cannot be retrieved.  Let me know if you have information otherwise.

Anyone else?
0
 
LVL 11

Expert Comment

by:NoiS
ID: 24150802
Weel... is strange cause you point to a memory address. Maybe when the script ends all values are cleaned like all PHP vars and objects.
I will make a test.
Remember that this functions are to be used on a Linux like system (will work on windows too but... ) and need PHP to be compile with --enable-shmop to activate it.

The persistence is the main trouble here.
I think that the only way to do what you want is using DB or File (if shmop cannot do it).
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:Geoff Millikan
ID: 24152309
My test was to run the below test via a HTTP call.  Then use the returned $shm_id value (which was "4" in my case) like the below at the command line:  Expected return was "100" but it threw errors instead.

shell prompt> php -r "var_dump(shmop_size(4));"

PS. I'm on Red Hat Linux 5 with PHP 5.1.6 (cli).
<?php
 
$shm_key = ftok(__FILE__, 't');
echo '$shm_key='.$shm_key."\r\n";
 
if ($shm_id = shmop_open($shm_key, "n", 0777, 100)) {
    echo '$shm_id='.$shm_id."\r\n";    
}
?>

Open in new window

0
 
LVL 11

Accepted Solution

by:
NoiS earned 500 total points
ID: 24157232
look... you are using ftok(__FILE__, 't') to generate a memory address
but you need the same address always.
Try changing __FILE__ to a fixed path to any file.

the code will be

#######################################################################
// To put the value on memory
 
// Create 100 byte shared memory block with system id if 0xff3
$shm_id = shmop_open(ftok('/path/to/file','t'), "c", 0666, 100);
if(!$shm_id) {
    echo "Couldn't create shared memory segment\n";
}
 
// Lets write a test string into shared memory
$shm_bytes_written = shmop_write($shm_id, "my shared memory block", 0);
if($shm_bytes_written != strlen("my shared memory block")) {
    echo "Couldn't write the entire length of data\n";
}
 
shmop_close($shm_id);
 
#######################################################################
// To read the value stored
$shm_id = shmop_open(ftok('/path/to/file','t'), "c", 0666, 100);
if(!$shm_id) {
    echo "Couldn't create shared memory segment\n";
}
 
// Now lets read the string back
$shm_size = shmop_size($shm_id);
$my_string = shmop_read($shm_id, 0, $shm_size);
if(!$my_string) {
    echo "Couldn't read from shared memory block\n";
}
echo "The data inside shared memory was: [".$my_string."]\n";
shmop_close($shm_id);
 
#######################################################################
// To release the address
$shm_id = shmop_open(ftok('/path/to/file','t'), "c", 0666, 100);
if(!$shm_id) {
    echo "Couldn't create shared memory segment\n";
}
//Now lets delete the block and close the shared memory segment
if(!shmop_delete($shm_id)) {
    echo "Couldn't mark shared memory block for deletion.";
}
shmop_close($shm_id);

Open in new window

0
 

Author Comment

by:Geoff Millikan
ID: 24159580
Output with test script below is:

From web browser:
12 $shm_id=2
20 $shm_bytes_written=22

From command line:
shell> php /home/t1shopper/www/dev/shared_memory.php
32 $shm_id=4
42 The data inside shared memory was: [my shared memory block]
bool(true)

NULL

<?php
if (php_sapi_name()=='apache2handler') {
    //Write memory with web browser
    $file_name='/home/t1shopper/www/dev/shared_memory.php';
    $shm_key = ftok($file_name, 't');
    $shm_id = shmop_open($shm_key, "c", 0777, 100);
 
    if (empty($shm_id)) {
        echo __LINE__." Couldn't create shared memory segment<br>";   
        exit(); 
    } else {
        echo __LINE__.' $shm_id='.$shm_id." <br>\n";   
    }
 
    $shm_bytes_written = shmop_write($shm_id, "my shared memory block", 0);
    if($shm_bytes_written != strlen("my shared memory block")) {
        echo "Couldn't write the entire length of data\n";
        exit();
    } else {
        echo __LINE__.' $shm_bytes_written='.$shm_bytes_written." <br>";   
    }
 
    shmop_close($shm_id);
} elseif (php_sapi_name()=='cli') {
    //Read out of memory using command line script.
    $file_name='/home/t1shopper/www/dev/shared_memory.php';
    $shm_key = ftok($file_name, 't');
    @$shm_id = shmop_open($shm_key, "w", 0777, 100);
    if (empty($shm_id)) {
        echo __LINE__." Couldn't access the shared memory segment\n";    
        exit();
    } else {
        echo __LINE__.' $shm_id='.$shm_id."\n";   
    }
     
    // Now lets read the string back
    $shm_size = shmop_size($shm_id);
    $my_string = shmop_read($shm_id, 0, $shm_size);
    if(empty($my_string)) {
        echo __LINE__." Couldn't read from shared memory block\n";
        exit();
    } else {
        echo __LINE__." The data inside shared memory was: [".$my_string."]\n";
        var_dump(shmop_delete($shm_id)); echo "\n";
        var_dump(shmop_close($shm_id));  echo "\n";
    }    
} 
?>

Open in new window

0
 

Author Comment

by:Geoff Millikan
ID: 24159600
P.S.  Running the below command show you everything that's in the shared memory.  Who the owner is, it's permissions and size.  Very helpful to confirm that your shared memory is created.

shell> ipcs
0
 

Author Comment

by:Geoff Millikan
ID: 24187756
Unfortunately, there's no way to incremental add and remove things from Shared memory like you would with a database.  Shared memory needs something like array_pop() and array_push().  As it is, in a threaded environment, I run the risk f overwriting something done on another thread.

Shared memory seems like its main purposes is mostly for times when the data you're reading is too big to fit in the disk cache so you're having to spin the disks each time you want to read the data.  In this case, it's faster to read it out of memory than spin the disks.  If you're reading just a small amount of data, then that will load out of the disk cache which should be in memory already.  It would be interesting to see benchmarking on this - it would differ greatly by operating system since each OS does file caching differently.

If you're needing to both read AND write data across page loads or threads, then shared memory probably isn't for you.  Look at MySQL's MEMORY table type as a better solution.
0

Featured Post

Revamp Your Training Process

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Generating table dynamically is the most common issue faced by php developers.... So it seems there is a need of an article that explains the basic concept of generating tables dynamically. It just requires a basic knowledge of html and little maths…
Build an array called $myWeek which will hold the array elements Today, Yesterday and then builds up the rest of the week by the name of the day going back 1 week.   (CODE) (CODE) Then you just need to pass your date to the function. If i…
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

710 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question