Вот алгоритм, который корректирует порядок конечных нулей, которые обычно возвращаются из форматированной даты String
.
/**
* Takes a Date and provides the format whilst compensating for the mistaken representation of sub-second values.
* i.e. 2017-04-03-22:46:19.000991 -> 2017-04-03-22:46:19.991000
* @param pDate Defines the Date object to format.
* @param pPrecision Defines number of valid subsecond characters contained in the system's response.
* */
private static final String subFormat(final Date pDate, final SimpleDateFormat pSimpleDateFormat, final int pPrecision) throws ParseException {
// Format as usual.
final String lString = pSimpleDateFormat.format(pDate);
// Count the number of characters.
final String lPattern = pSimpleDateFormat.toLocalizedPattern();
// Find where the SubSeconds are.
final int lStart = lPattern.indexOf('S');
final int lEnd = lPattern.lastIndexOf('S');
// Ensure they're in the expected format.
for(int i = lStart; i <= lEnd; i++) { if(lPattern.charAt(i) != 'S') {
// Throw an Exception; the date has been provided in the wrong format.
throw new ParseException("Unable to process subseconds in the provided form. (" + lPattern + ").", i);
} }
// Calculate the number of Subseconds. (Account for zero indexing.)
final int lNumSubSeconds = (lEnd - lStart) + 1;
// Fetch the original quantity.
String lReplaceString = lString.substring(lStart + (lNumSubSeconds - pPrecision), lStart + lNumSubSeconds);
// Append trailing zeros.
for(int i = 0; i < lNumSubSeconds - pPrecision; i++) { lReplaceString += "0"; }
// Return the String.
return lString.substring(0, lStart) + lReplaceString;
}
По умолчанию это просто невозможно. Каждое решение всегда будет копировать содержимое в текущую область, потому что, если нет, нет доступа к нему.
Я не знаю, что именно нужно делать, но, возможно, вы можете сделать это «снаружи», , например, как задание gearman , а затем просто поймать результаты процесса, а не весь массив.
Вы также можете подумать о разделении «большого» массива на и затем всегда извлекать нужную вам часть из apc или memcached.
PHP имеет магические методы:
__get($property)
позволяет реализовать доступ свойства $ к объекту __set($property, $value)
, чтобы реализовать назначение $ свойство на объекте PHP может сериализовать переменные:
serialize($variable)
возвращает строковое представление переменной unserialize($string)
возвращает обратно переменную из строки PHP может обрабатывать файлы с управлением с одновременным доступом:
fopen($file, 'c+')
открывает файл с рекомендациями блокировки (для чтения) flock($descriptor, LOCK_EX)
использует эксклюзивную блокировку (для записи) flock($descriptor, LOCK_SH)
g18] Таким образом, самый простой способ совместного использования объекта между приложениями - создать класс, который реализует и использует все эти материалы для сохранения и мгновенного восстановления всех своих данных в файл.
Простая реализация этого класса может быть:
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, вы можете найти его здесь .
Использование Shmop
:
Shmop - это простой в использовании набор функций, который позволяет PHP читать, записывать, создавать и удалять сегменты разделяемой памяти Unix.
blockquote >from: http://www.php.net/manual/en/intro.shmop.php
Для создания этого расширение
Общие функции памяти
- shmop_close - Закрыть
- блок разделяемой памяти
- shmop_delete - Удалить блок общей памяти
- shmop_open - создать или открыть блок разделяемой памяти
- shmop_read - прочитать данные из блока разделяемой памяти
- shmop_size - получить размер блока разделяемой памяти
- shmop_write - Запись данных в блок разделяемой памяти
Основное использование
// 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);
Одним из способов обмена памятью между PHP-процессами является установка кеша PHP-байт-кода, такого как APC . APC в основном используется для хранения байт-кода в сегменте разделяемой памяти OS, но у него также есть API для совместного использования всего, что вы хотите между процессами (например, локальная версия memcache).
<?php
$foobar = array('foo', 'bar');
apc_store('foobar', $foobar);
?>
Затем в другом месте:
<?php
$foobar = apc_fetch('foobar');
var_dump($foobar);
?>
. Большая проблема с памятью обмена заключается в том, что для процессов очень легко ступить друг на друга. Таким образом, общая память лучше всего подходит для вещей, которые не меняются слишком сильно, как большие глобальные массивы.
Изменить: Вероятно, вы используете неправильную комбинацию разделяемой памяти. Сама ваша общая память является таким массивом. Таким образом, вы должны хранить отдельные многоязычные строки непосредственно в разделяемой памяти, а не большой массив с ними. а затем вытаскивать только строки, требуемые на конкретной странице. это все.
Как правило, для обработки некоторых данных программа должна «дублировать» ее, сохраняя ее в переменной. Вот какие переменные предназначены для хранения (или «дублирования») некоторых внешних данных. Например, если у вас есть какая-либо информация о пользователе в вашей базе данных, чтобы отобразить имя пользователя на веб-странице, вы должны «дублировать» эти данные, сначала сохраняя ее в переменной PHP. И так далее.
Вы первый, кто думает, что такой подход нужно изменить.