Solved

PHP > Setting server-wide variables?

Posted on 2009-04-15
8
279 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
  • 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
 

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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

This article will explain how to display the first page of your Microsoft Word documents (e.g. .doc, .docx, etc...) as images in a web page programatically. I have scoured the web on a way to do this unsuccessfully. The goal is to produce something …
I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
The viewer will learn how to dynamically set the form action using jQuery.
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.

914 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now