Ваш логин:

Ваш пароль:





Теперь подробнее о методах передачи данных. Существует два вида GET (через url, открытый - можно изменить url вручную) и POST (через форму, закрытый). Отличие будет заключаться в содержании адресной строки, то есть url.

При получении данных переданных одним из этих способов в массив соответствующего методу типа ($_GET или $_POST) собираются данные. Также существует массив $_REQUEST, который может содержать и $_GET, и $_POST одновременно. Но это для других примеров. Рекомендую большинство данных передавать методом POST.

Теперь рассмотрим код обработчика.

Код PHP (в файле test_reg.php)

$login = $_POST["login"]; // принимаем данные отправленные POST
$pass = $_POST["pass"]; // login и pass - это name полей ввода

If (($login == "Admin") && ($pass == "Pass"))
echo "Здравствуйте, Admin! Сегодня кофе или чай?)";
else echo "Вы ввели неверную связку логин-пароль. Попробуйте ещё Назад";
?>
Вы можете видеть как в отдельные переменные мы записываем значение полей с соответствующими name в массиве $_POST, хотя также можно было собрать и в $_REQUEST.

В обработчике, пожалуй, проработаем условие авторизации - совпадают ли логин и пароль в форме с нашим выдуманным (соответственно Admin и Pass). И либо поздороваемся с входящим (Здравствуйте, Admin! Сегодня кофе или чай?), либо нет (Вы ввели неверную связку логин-пароль. Попробуйте ещё). Однако для создания полноценной авторизации Вам ещё надо ознакомиться с cookie, сессиями и . Но об этом позже.

Непосредственно в скрипте можно как угодно обрабатывать данные: дописывать, стирать, шифровать и так далее. Главное - это знать имя переменной (задаётся в HTML-форме) и дальше собирать их с помощью массивов $_POST, $_GET и $_REQUEST.

Спасибо за внимание!

В статье описана организация мультизапросов средствами PHP с использованием библиотеки cURL. Данный механизм предполагается использовать для создания скриптов, осуществляющих автоматизированные запросы ко множеству веб-серверов.

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

В тех случаях, когда необходимо сделать запрос к одному веб-серверу, вполне достаточно обычных средств cURL, однако если требуется формировать большое количество веб-запросов, то применение механизма многопоточности может дать существенный прирост производительности и ускорение работы скрипта.

Прежде чем начать описывать механизм разработки скриптов сначала о том, что же я подразумеваю под многопоточностью. Дело тут в том, что ни какой многопоточности в PHP на самом деле нет и когда употребляется термин «многопоточность » касательно библиотеки cURL, то речь идет о мультизапросах.

Механизм мультизапросов заключается в том, что во время посылки запросов веб-серверам, PHP не дожидается ответа от каждого поочередно посланного запроса, а посылает (опять же поочередно) сразу несколько запросов, и уже после этого обрабатывает приходящие от них ответы. Поэтому применять многопоточность имеет смысл только тогда, когда осуществляются запросы к разным серверам – если необходимо осуществить большое количество запросов к одному серверу, то многопоточность не принесет заметного увеличения производительности скрипта.

Сразу хочу заметить, что средства работы с многопоточностью в cURL весьма скудные, но даже с теми что есть можно организовать полноценную работу с мультизапросами.

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

1. Список всех URI помещаем в массив
2. Создаем массив «обычных» cURL в требуемом количестве (количество потоков) и один cURL_multi
3. Инициализируем каждый созданный cURL (URL из подготовленного ранее массива, переменные post, если требуется, прокси и т.д.)
4. Добавляем каждый cURL в cURL_multi
5. Запускаем все потоки при помощи вызова cURL_multi
6. В цикле опрашиваем состояние cURL_multi и если есть отработавший поток, обрабатываем полученную страницу и на его место запускаем новый cURL. Если список URI закончился, то только обрабатываем результат. Цикл продолжается до тех пор, пока есть хотя бы один незавершенный поток.
7. Закрываем все cURL.

Теперь, собственно, скрипт который выполняет данную операцию:

    function Parse(&$urls ,$flowcount ) {

    // $urls — массив с URL-адресами

    // $flowcount — количество потоков

    //Запуск потоков

    $ch =array () ;

    $lcount0 =count ($urls ) ;

    if ($flowcount >$lcount0 ) $flowcount =$lcount0 ;

    for ($flow =0 ;$flow <$flowcount ;$flow ++) $ch =curl_ini(array_pop ($urls ) ) ; //создание массива cURL

    $mh =curl_multi_init() ; //создание cURL_multi

    for ($flow =0 ;$flow <$flowcount ;$flow ++) { //В этом цикле инициализируются cURL

    curl_setopt($ch [ $flow ] ,CURLOPT_REFERER,‘TESTREFERER’ ) ;

    curl_setopt($ch [ $flow ] ,CURLOPT_USERAGENT,” ) ;

    curl_setopt($ch [ $flow ] ,CURLOPT_RETURNTRANSFER,1 ) ;

    curl_setopt($ch [ $flow ] ,CURLOPT_POST,1 ) ;

    curl_setopt($ch [ $flow ] ,CURLOPT_POSTFIELDS,‘TEST=TESTVAR’ ) ;

    curl_setopt($ch [ $flow ] ,CURLOPT_COOKIE,‘TEST=TESTCOOKIE’ ) ;

    curl_multi_add_handle($mh ,$ch [ $flow ] ) ;

    $flows =null ;

    do { //Основной цикл, продолжается до тех пор, пока есть хотябы один работающий поток

    do curl_multi_exec($mh ,$flows ) ; while ($flows ==$flowcount ) ; //циклическая проверка количества работающих потоков

    $info =curl_multi_info_read($mh ) ;

    if (!count ($urls ) ) { //Больше нет URL для обработки

    curl_close($info [ ‘handle’ ] ) ;

    $flowcount –;

    } else { //Есть еще URL для обработки

    curl_setopt($info [ ‘handle’ ] ,CURLOPT_URL,array_pop ($urls ) ) ;

    $res =curl_multi_getcontent($info [ ‘handle’ ] ) ;

    curl_multi_remove_handle($mh ,$info [ ‘handle’ ] ) ;

    В тексте кода достаточно комментариев, чтобы разобраться что происходит. Поясню несколько моментов…

    1. Вызов curl_multi_init должен быть осуществлен ОБЯЗАТЕЛЬНО после того, как все “обычные” cURL будут проинициализированы, т.е. нельзя поменять 9ю и 10ю строки местами, поэтому участки кода по инициализации $ch и задания необходимых параметров разделены.

    2. При каждом вызове curl_multi_exec в строке 22 в переменную $flows помещается количество активных потоков, которое далее сравнивается с количеством запущенных потоков (переменная $flowcount будет уменьшаться, если в списке обрабатываемых URL (массив $urls) больше нет записей).

    3. curl_multi_info_read возвращает информацию об очередном отработавшем потоке, или false, если с момента предыдущего вызова этой функции никаких изменений небыло.

    4. Функция curl_multi_info_read обновляет данные, помещаемые в переменную $info только после того, как будет выполнен curl_multi_exec, поэтому для обработки каждого потока необходимо использовать обе функции.

    5. Чтобы добавить новый поток необходимо последовательно выполнить вызов трех функций: curl_multi_remove_handle, curl_multi_add_handle и curl_multi_exec.

    Ну и последнее: иногда важно знать какую-либо дополнительную информацию, связанную с обрабатываемым потоком. В этом случае можно создать ассоциативный массив, ключами которого будут являться идентификаторы потока, т.е. значения в $info[‘handle’].

Иногда появляется необходимость выполнять несколько действий одновременно, например, проверять изменения в одной таблице БД и вносить модификации в другую. Причем если одна из операций (например, проверка изменений), занимает много времени, очевидно, что последовательное выполнение не обеспечит балансировки ресурсов.

Для решения такого рода задач, в программировании используется многопоточность - каждая операция помещается в отдельный поток с выделенным объемом ресурсов и работает внутри него. При таком подходе, все задачи будут выполнятся отдельно и независимо.

Хотя PHP и не поддерживает многопоточность, есть несколько методов её эмуляции, о них и пойдет речь ниже.

1. Запуск нескольких копий скрипта - по копии для операции

//woman.php if (!isset($_GET["thread"])) { system("wget http://localhost/woman.php?thread=make_me_happy"); system("wget http://localhost/woman.php?thread=make_me_rich"); } elseif ($_GET["thread"] == "make_me_happy") { make_her_happy(); } elseif ($_GET["thread"] == "make_me_rich") { find_another_one(); }

Когда мы выполняем этот скрипт без параметров, он автоматически запускает две копии себя, с идентификаторами операций ("thread=make_me_happy" и "thread=make_me_rich"), которые инициируют выполнение необходимых функций.

Таким образом мы достигаем нужного результата - две операции выполняются одновременно - но это конечно же не многопоточность, а просто костыль для выполнения задач одновременно.

2. Путь джедая - использование расширения PCNTL

PCNTL - расширение, позволяющее полноценно работать с процессами. Кроме управления, поддерживает отправку сообщений, проверку состояния и установку приоритетов. Вот так выглядит предыдущий скрипт с использованием PCNTL:

$pid = pcntl_fork(); if ($pid == 0) { make_her_happy(); } elseif ($pid > 0) { $pid2 = pcntl_fork(); if ($pid2 == 0) { find_another_one(); } }

Выглядит довольно запутанно, пройдемся построчно.

В первой строке мы "форкаем" текущий процесс (форк - копирование процесса из сохранением значений всех переменных), разделяя на два процесса (текущий и дочерний) выполняющихся параллельно.

Чтобы понять, где мы находимся в данный момент, в дочернем или материнском процессе, функция pcntl_fork возвращает 0 для дочернего и идентификатор процесса для материнского. Поэтому, во второй строке, мы смотрим на $pid, если он равен нулю, значит мы в дочернем процессе - выполняем функцию, в противном случае, мы находимся в материнском (строка 4), тогда создаем еще один процесс и аналогично выполняем задачу.

Процесс выполнения скрипта:

Таким образом скрипт создает еще 2 дочерних процесса, которые являются его копиями, содержат те же переменные с аналогичными значениями. А при помощи идентификатора возвращаемого функцией pcntl_fork мы ориентируемся в каком потоке находимся в данный момент и выполняем необходимые действия.

В программировании постоянно приходиться работать с различными ресурсами: файлами, сокетами, http-соединениями . И у них у всех есть некий интерфейс доступа, часто несовместимый друг с другом. Поэтому, чтобы устранить данные несоответствия и унифицировать работу с различными источниками данных, начиная с PHP 4.3 были придуманы PHP Streams - потоки .

Несмотря на то, что PHP 4.3 вышел давным-давно, многие PHP-программисты имеют весьма отдаленное представление о потоках в PHP , и продолжают использовать CURL везде, хотя в PHP для этого существует более удобная альтернатива в виде контекста потоков (Stream Context) .

Следующие виды потоков существуют в PHP :

Что общего есть во всех этих ресурсах? Все они могут быть прочитаны и записаны, т.е. к ним ко всем могут быть применены операции чтения и записи. Сила потоков PHP как раз и заключается в том, что вы можете получить доступ ко всем этим ресурсам, используя один и тот же набор функций. Это очень удобно. Также, если вдруг возникнет такая необходимость, Вы можете написать свою собственную реализацию обработчика потоков "stream wrapper" . Помимо чтения и записи, потоки в PHP также позволяет выполнять другие операции, такие как переименование и удаление.

Программируя на PHP , Вы уже встречались с потоками, хотя возможно не догадывались об этом. Так, функции, работающие с потоками - это fopen() , file_get_contents() , file() и т.д. Поэтому, фактически, Вы уже используете файловые потоки все это время, полностью прозрачно.

Для работы с другим типом потока, необходимо указать его протокол (wrapper) следующим образом: wrapper://some_stream_resource , где wrapper:// - это, например http:// , file:// , ftp:// , zip:// и т.д., а some_stream_resource - URI-адрес , идентифицирует то, что вы хотите открыть. URI-адрес не накладывает каких-либо ограничений на формат. Примеры:

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

// список зарегистрированных транспортов сокета
print_r(stream_get_transports());

// список зарегистрированных потоков (обработчиков)
print_r(stream_get_wrappers());

// список зарегистрированных фильтров
print_r(stream_get_filters();

Контексты потоков PHP

Часто возникает необходимость указания дополнительных параметров при http-запросе. Контексты потоков решают эту проблему, позволяя указать дополнительные параметры. У многих функций, поддерживающих работу с потоками, есть необязательный параметр контекста потока. Давайте посмотрим на функцию file_get_contents() :

String file_get_contents(string $filename [, int $flags = 0 [, resource $context [, int $offset = -1 [, int $maxlen = -1]]]])

Как видно, третьим параметром передается контекст потока. Контексты создаются с помощью функции stream_context_create() , которая принимает массив и возвращает ресурс контекста.

$options = array(
"http" => array(
"method" => "GET",
"header" => "Accept-language: en\r\n".
"Cookie: foo = bar\r\n"
);

$context = stream_context_create($options);

// Используя это с file_get_contents ...
echo file_get_contents ("http://www.example.com/", 0, $context);

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

Оффициальной нет, сразу скажу. Есть только многочисленные костылики. Примеры, в основном, будут полезны в сео софте.

Встала вобщем задача передо мной — накатать многопоточный нескажу что, причем не просто многопоточный, а чтобы еще и потоками можно было управлять, как в том же делфи. То есть, чтобы можно было поток остановить, запустить, запауазить, возобновить и потоки еще должны оповещать о своем состоянии, мол в данный момент выполняю то-то.

Собсно, теория реализации.

Два скрипта — один поток, второй запускалка потоков. Поток делает свои дела, запускалка вычисляет, сколько потоков запустить и с какими параметрами.

Пример первый, запускает 20 потоков, если общее количество потоков ниже чем 10

1): $thCount = exec("ps a | thread.php | wc -l"); echo $thCount."\r\n"; if($thCount < 10){ for($i = 0; $i < 20; $i++){ echo "launch thread\r\n"; passthru("(php -f thread.php &) >> /dev/null 2>&1"); //sleep(1); } } else { sleep(5); } endwhile; ?>

Получается хрень, которая дозапускает потоки время от времени по условию. Потоков всегда разное число в разные промежутки времени и остановить их никак нельзя. Но, если некритичны все эти вещи, цикл вполне неплохо работает. Подходит, например, всякие регеры. При допилке можно держать нужное количество потоков с погрешностью +- 1. Для этого нужно просто динамически вычислять число запускаемых потоков. Да, и ps показывает три работающих потока при таком вызове, даже если нет ни одного. Один дает греп, второй сам скрипт, третий фиг знает кто.

Вариант 2.

Тут уже захотелось сделать более гибкую штуку. А именно — взять например 1к урлов и раздать их поровну N потокам.

> /dev/null 2>&1"); } if($i == $threads-1) { passthru("(php -f thread.php "".$perThread * $i."|".count($base)."" &) >> /dev/null 2>&1"); } if(($i !== 0)&&($i !== $threads-1)) { $start = $perThread * $i + 1; $end = $start -1 + $perThread; passthru("(php -f thread.php "".$start."|".$end."" &) >> /dev/null 2>&1"); } } ?>

Данный пример запускает поток с параметрами, который тот потом достает из массива $argv и использует. Такое вот разделение труда.

Взаимодействие между потоком и «мамой».
Тут у меня только теория. Думаю реализовать это через файлы. Поток создает файл с именем своей сессии (номера, пида), мама читает оттуда. Чтобы вывести инфу о потоках красиво и наглядно, думаю заюзать ncurses . Это сишная либа, на ней сделаны midnight commander, top. Доступна не только для пхп.

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

Саня, он же похапэ дуд , сразу обрубил — Я бы такие задачи не решал на php. Я тоже посматриваю в сторону других языков, думаю выучить что-то типа си, но пока я выучу, мне наверно уже ничего не надо будет. Есть вариант на питоне. И как раз в ридере попалась статья одного камрада, который начал изучать его и

Читайте также
Версия для печати

Последние материалы сайта

Жимолость

К чему снится старая обувь девушке

К чему снится старая обувь девушке

2022-04-11 17:16:12

Сонник обувь. Любая обувь во сне означает дорогу, как в прямом, так и в переносном смысле. То есть, может указывать на символическую дорогу в отношениях с кем-либо, работе, деятельности. Например, снится новая обувь, если во сне она была красивой, добротн

Цветы

К чему снится мяч: толкование по разным сонникам

К чему снится мяч: толкование по разным сонникам

2022-04-11 17:16:12

К чему снится мяч женщине: Походите по чиновничьим кабинетам. 1 Мяч по Соннику целительницы Федоровской Видеть мяч во сне значит: Если вам приснилось, что вы бросаете мячик - вскоре вас обидит близкий друг.Если вам приснилось, что вы вспарывает

Капуста

Ленивая лазанья с грибами Ленивая лазанья с лавашом

Ленивая лазанья с грибами Ленивая лазанья с лавашом

2022-04-01 02:39:40

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

Томаты

Рис с мясом в духовке Рис запеченный в духовке с мясом

Рис с мясом в духовке Рис запеченный в духовке с мясом

2022-04-01 02:39:40

Рис с мясом в духовке, как и любое другое блюдо, имеет множество интерпретаций приготовления. В данном обзоре представлен самый простой вариант с минимальными трудозатратами. Пошаговый рецепт с фото. Видео-рецепт. Мясо с рисом - самое классическое со

Клубника

Как правильно выбрать паевой инвестиционный фонд (ПИФ)

Как правильно выбрать паевой инвестиционный фонд (ПИФ)

2022-03-25 19:21:49

г. Москва Компания "УПРАВЛЯЮЩАЯ ФИНАНСОВАЯ ИНВЕСТИЦИОННАЯ КОМПАНИЯ" зарегистрирована 29 мая 2014 года местным органом ФНС — Межрайонная инспекция Федеральной налоговой службы №46 по г. Москве. Полное официальное наименование — ОБЩЕСТВО С ОГРАНИЧЕННОЙ ОТ

Огурцы

Столбчатый фундамент своими руками — пошаговая инструкция

Столбчатый фундамент своими руками — пошаговая инструкция

2022-03-19 13:37:32

Практически все счастливые владельцы частных домов, коттеджей или дачных домиков хотели бы иметь на своем участке отдельно стоящую баню. Для ее возведения можно воспользоваться услугами профессиональных строителей или же соорудить баньку самостоятельно. О