• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 359
  • Last Modified:

PHP > Setting server-wide variables?

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
Geoff Millikan
Asked:
Geoff Millikan
  • 5
  • 3
1 Solution
 
NoiSCommented:
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
 
Geoff MillikanAuthor Commented:
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
 
NoiSCommented:
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
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
Geoff MillikanAuthor Commented:
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
 
NoiSCommented:
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
 
Geoff MillikanAuthor Commented:
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
 
Geoff MillikanAuthor Commented:
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
 
Geoff MillikanAuthor Commented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now