을 복제하지 않고 모든 PHP 프로세스 간에 변수 및 배열을 공유 할 수 있습니까?모든 PHP 프로세스간에 변수/메모리 공유
memcached를 사용하여, 나는 PHP가 사용하는 메모리를 복제 생각 :
$array = $memcache->get('array');
$ 배열되는 memcached에서 사본을 포함합니다.
제 생각에는 정적 변수가 이미 정의되어 있고 모든 프로세스간에 공유되어있을 수 있습니다.
을 복제하지 않고 모든 PHP 프로세스 간에 변수 및 배열을 공유 할 수 있습니까?모든 PHP 프로세스간에 변수/메모리 공유
memcached를 사용하여, 나는 PHP가 사용하는 메모리를 복제 생각 :
$array = $memcache->get('array');
$ 배열되는 memcached에서 사본을 포함합니다.
제 생각에는 정적 변수가 이미 정의되어 있고 모든 프로세스간에 공유되어있을 수 있습니다.
기본적으로 불가능합니다. 모든 솔루션은 항상 현재 범위에 내용을 복사합니다. 그렇지 않으면 액세스하지 못하게됩니다.
정확하게 알고 싶지 않지만, 예를 들어 gearman 작업과 같이 "외부"작업을 수행 한 다음 전체 배열 대신 프로세스의 결과를 캐치 할 수 있습니다.
또한 "큰"배열을 조각으로 분할 한 다음 항상 apc 또는 memcached에서 현재 필요한 부분을 검색 할 수 있습니다.
편집 :
아마도 공유 메모리를 잘못 사용하고있을 수 있습니다.
공유 메모리 자체가 배열입니다. 그래서 별도의 다국어 문자열을 공유 메모리에 직접 저장해야하며 큰 배열은 저장하지 않아야합니다.
다음 특정 페이지에 필요한 문자열 만 당깁니다.
그게 전부입니다.
일반적으로 일부 데이터를 처리하려면 프로그램에 변수를 저장하여 "복제"해야합니다.
그게 변수입니다. - 외부 데이터를 저장 (또는 "복제")하는 것입니다.
예를 들어 데이터베이스에 사용자 정보가있는 경우 웹 페이지에 사용자 이름을 표시하려면이 데이터를 "복제"하여 PHP 변수에 먼저 저장해야합니다.
등등.
이러한 접근 방식을 변경해야한다고 생각하는 사람이 누구입니까?
PHP 프로세스간에 메모리를 공유하는 한 가지 방법은 APC과 같은 PHP 바이트 코드 캐시를 설치하는 것입니다. APC는 주로 바이트 코드를 OS 관리 공유 메모리 세그먼트에 저장하는 데 사용되지만 프로세스간에 원하는 내용 (예 : memcache의 로컬 버전)을 공유하기위한 API도 제공합니다. 그런 다음 다른 곳
<?php
$foobar = array('foo', 'bar');
apc_store('foobar', $foobar);
?>
: 공유 메모리와
<?php
$foobar = apc_fetch('foobar');
var_dump($foobar);
?>
큰 문제는 두 프로세스가 서로의 발을 단계로 매우 쉽게 될 것입니다. 따라서 공유 메모리는 큰 글로벌 배열처럼 너무 많이 변경되지 않는 것들에 가장 좋습니다.
PHP는 매직 메소드가 있습니다
__get($property)
는__set($property, $value)
우리가 물체에 $ 속성의 대입을 구현할 수 있도록 우리가 물체에 $ 속성의 액세스를 구현할 수 있도록PHP는 변수를 직렬화 할 수 있습니다 :
unserialize($string)
반환의 문자열 표현은 문자열에서 변수를 다시:
fopen($file, 'c+')
이 자문 잠금 옵션이있는 파일을 엽니 다 사용 가능 (무리 사용 허용)flock($descriptor, LOCK_SH)
은 공유 잠금을 사용합니다 (읽기 용)flock($descriptor, LOCK_EX)
따라서 앱간에 개체를 공유하는 가장 쉬운 방법은 모든 데이터를 구현하고 사용하여 모든 데이터를 즉시 저장하고 파일에 복원하는 클래스를 만드는 것입니다.
클래스의 간단한 구현 될 수있다 : 구성 할 때
class Synchro
{
private $_file;
public function __construct($file)
{
$this->_file = $file;
}
public function __get($property)
{
// File does not exist
if (!is_file($this->_file))
{
return null;
}
// Check if file is readable
if ((is_file($this->_file)) && (!is_readable($this->_file)))
{
throw new Exception(sprintf("File '%s' is not readable.", $this->_file));
}
// Open file with advisory lock option enabled for reading and writting
if (($fd = fopen($this->_file, 'c+')) === false)
{
throw new Exception(sprintf("Can't open '%s' file.", $this->_file));
}
// Request a lock for reading (hangs until lock is granted successfully)
if (flock($fd, LOCK_SH) === false)
{
throw new Exception(sprintf("Can't lock '%s' file for reading.", $this->_file));
}
// A hand-made file_get_contents
$contents = '';
while (($read = fread($fd, 32 * 1024)) !== '')
{
$contents .= $read;
}
// Release shared lock and close file
flock($fd, LOCK_UN);
fclose($fd);
// Restore shared data object and return requested property
$object = json_decode($contents);
if (property_exists($object, $property))
{
return $object->{$property};
}
return null;
}
public function __set($property, $value)
{
// Check if directory is writable if file does not exist
if ((!is_file($this->_file)) && (!is_writable(dirname($this->_file))))
{
throw new Exception(sprintf("Directory '%s' does not exist or is not writable.", dirname($this->_file)));
}
// Check if file is writable if it exists
if ((is_file($this->_file)) && (!is_writable($this->_file)))
{
throw new Exception(sprintf("File '%s' is not writable.", $this->_file));
}
// Open file with advisory lock option enabled for reading and writting
if (($fd = fopen($this->_file, 'c+')) === false)
{
throw new Exception(sprintf("Can't open '%s' file.", $this->_file));
}
// Request a lock for writting (hangs until lock is granted successfully)
if (flock($fd, LOCK_EX) === false)
{
throw new Exception(sprintf("Can't lock '%s' file for writing.", $this->_file));
}
// A hand-made file_get_contents
$contents = '';
while (($read = fread($fd, 32 * 1024)) !== '')
{
$contents .= $read;
}
// Restore shared data object and set value for desired property
if (empty($contents))
{
$object = new stdClass();
}
else
{
$object = json_decode($contents);
}
$object->{$property} = $value;
// Go back at the beginning of file
rewind($fd);
// Truncate file
ftruncate($fd, strlen($contents));
// Save shared data object to the file
fwrite($fd, json_encode($object));
// Release exclusive lock and close file
flock($fd, LOCK_UN);
fclose($fd);
return $value;
}
}
지금, 당신은 stdClass
처럼이 클래스를 사용하지만, 파일 경로로 할 수 있습니다.
$obj = new Synchro("/tmp/test.sync");
$obj->hello = 'world';
// ... and in another process...
echo $obj->hello;
이 예제는 당신이 뮤텍스와 같은 잠금 장치를 사용합니다 더 나은 구현, 파일에 대한 동시 액세스에 대해서가 아니라 변수로 처리합니다, 물론 매우 간단합니다.
github에서이 클래스를 푸시했습니다 (here). Shmop
를 사용
:
은 shmop는 PHP는 유닉스 공유 메모리 세그먼트를 읽고 쓰기, 생성 및 삭제할 수 있습니다이 기능의 설정 사용하기 쉽습니다.
은에서 : http://www.php.net/manual/en/intro.shmop.php
외부 라이브러리는이 확장을 만들 필요하지 않습니다.
공유 메모리 기능
기본 사용법
// Create 100 byte shared memory block with system id of 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);
이 배열이 큰 것입니다 - 공유 메모리 블럭의 크기
예. 컨텍스트를 조금 더 추가 할 수 있습니까? 데이터를 데이터베이스에 저장하고 현재 스크립트에서 필요한 비트만 검색하는 방법은 무엇입니까? –
이것은 대개 데이터베이스에 데이터를 저장하고 필요한 것을 가져 오는 것으로 해결됩니다. –