Как запустить глобальный процесс в PHP? [Дубликат]

Вот алгоритм, который корректирует порядок конечных нулей, которые обычно возвращаются из форматированной даты 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;
}
18
задан Nuno 31 May 2013 в 18:40
поделиться

5 ответов

По умолчанию это просто невозможно. Каждое решение всегда будет копировать содержимое в текущую область, потому что, если нет, нет доступа к нему.

Я не знаю, что именно нужно делать, но, возможно, вы можете сделать это «снаружи», , например, как задание gearman , а затем просто поймать результаты процесса, а не весь массив.

Вы также можете подумать о разделении «большого» массива на и затем всегда извлекать нужную вам часть из apc или memcached.

3
ответ дан KingCrunch 19 August 2018 в 11:43
поделиться
  • 1
    Хорошо, наконец, полезный ответ: «невозможно». Я скорее искренность, чем оскорбления или сарказмы. Спасибо, это мой принятый ответ. – Nuno 9 April 2011 в 17:47
  • 2
    Что касается вашего третьего абзаца, я использую этот метод уже для других вещей. Мое беспокойство - это когда я не знаю, что происходит, как я сказал в своем вопросе. – Nuno 9 April 2011 в 17:49
  • 3
    @Nuno не так уж и трогательно. Никто не оскорбил вас. Если ответ вам не помог, попробуйте улучшить свой вопрос, вместо того, чтобы чувствовать боль. – Your Common Sense 9 April 2011 в 17:51
  • 4
    @YourCommonSense, вопрос выглядит достаточно хорошо. Как вы могли бы улучшить его? – Pacerier 19 January 2015 в 08:10

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, вы можете найти его здесь .

4
ответ дан Alain Tiemblo 19 August 2018 в 11:43
поделиться
  • 1
    Вы неправильно поняли этот вопрос. – Pacerier 19 January 2015 в 08:11
  • 2
    как это ... использование файла - это, пожалуй, самый простой способ и более безопасный способ, потому что нет попытки использовать память сервера. Я думаю, что это быстрее, чем просить базу данных. – Meloman 7 July 2017 в 13:32
  • 3
    это ничем не отличается от использования базы данных, идея заключается в совместном использовании переменных в памяти, а не на диске. – Pablo Pazos 6 November 2017 в 03:52

Использование Shmop:

Shmop - это простой в использовании набор функций, который позволяет PHP читать, записывать, создавать и удалять сегменты разделяемой памяти Unix.

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);
19
ответ дан RafaSashi 19 August 2018 в 11:43
поделиться

Одним из способов обмена памятью между PHP-процессами является установка кеша PHP-байт-кода, такого как APC . APC в основном используется для хранения байт-кода в сегменте разделяемой памяти OS, но у него также есть API для совместного использования всего, что вы хотите между процессами (например, локальная версия memcache).

<?php
   $foobar = array('foo', 'bar');
   apc_store('foobar', $foobar);
?>

Затем в другом месте:

<?php
    $foobar = apc_fetch('foobar');
    var_dump($foobar);
?>

. Большая проблема с памятью обмена заключается в том, что для процессов очень легко ступить друг на друга. Таким образом, общая память лучше всего подходит для вещей, которые не меняются слишком сильно, как большие глобальные массивы.

8
ответ дан wm_eddie 19 August 2018 в 11:43
поделиться
  • 1
    Это похоже на Memcached. Спасибо за ваш ответ, так или иначе :) – Nuno 9 April 2011 в 17:35
  • 2
    @NunoPeralta, Как насчет Shmop? Смотри ниже. – Pacerier 19 January 2015 в 08:11
  • 3
    Это неправильно, apc_store и т. Д. Не могут совместно использовать память между процессами. Каждый процесс выделяет свой собственный сегмент памяти. вы можете i.e не разделить память между php-fpm и php-cli по этой причине (при совместном использовании разных запросов php-fpm). – bhelm 7 July 2016 в 09:15

Изменить: Вероятно, вы используете неправильную комбинацию разделяемой памяти. Сама ваша общая память является таким массивом. Таким образом, вы должны хранить отдельные многоязычные строки непосредственно в разделяемой памяти, а не большой массив с ними. а затем вытаскивать только строки, требуемые на конкретной странице. это все.

Как правило, для обработки некоторых данных программа должна «дублировать» ее, сохраняя ее в переменной. Вот какие переменные предназначены для хранения (или «дублирования») некоторых внешних данных. Например, если у вас есть какая-либо информация о пользователе в вашей базе данных, чтобы отобразить имя пользователя на веб-странице, вы должны «дублировать» эти данные, сначала сохраняя ее в переменной PHP. И так далее.

Вы первый, кто думает, что такой подход нужно изменить.

0
ответ дан Your Common Sense 19 August 2018 в 11:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: