Сборник советов и фактов по оптимизации PHP-скриптов. Оттачиваем мастерство работы с cURL Оптимизация на уровне логики и организации приложения

Как правильно искать с помощью google.com

Все наверное умеют пользоваться такой поисковой системой, как гугл =) Но не все знают, что если грамотно составить поисковой запрос с помощью специальных конструкций, то можно достичь результатов того, что Вы ищете намного эффективнее и быстрее =) В этой статье я постараюсь показать что и как Вам нужно делать, чтобы искать правильно

Гугл поддерживает несколько расширенных операторов поиска, имеющими специальное значение при поиске на google.com. Типично, эти операторы изменяют поиск, или даже говорят гуглу делать полностью различные типы поиска. Например, конструкция link: является специальным оператором, и запрос link:www.google.com не даст вам нормального поиска, но вместо этого найдет все web-страницы, которые имеют связи к google.com.
альтернативные типы запросов

cache: Если Вы будете включать другие слова в запрос, то Гугл подсветит эти включенные слова в пределах кэшируемого документа.
Например, cache:www.сайт web покажет кэшируемое содержимое с подсвеченным словом "web".

link: рассматриваемый выше поисковой запрос покажет веб-страницы, на которых содержатся ссылки к указанному запросу.
Например: link:www.сайт отобразит все страницы на которых есть ссылка на http://www.сайт

related: Отобразит web-страницы, которые являются "подобными" (related) указанной web-странице.
Например, related: www.google.com перечислит web-страницы, которые являются подобными домашней странице Гугл.

info: Информация запроса: представит немного информации, которую Гугл имеет о запрашиваемой web-странице.
Например, info:сайт покажет информацию о нашем форуме =) (Армада - Форум адалт вебмастеров).

Другие информационные запросы

define: Запрос define: обеспечит определение слов, которые Вы вводите после того, как это, собранный из различных сетевых источников. Определение будет для всей введенной фразы (то есть, это будет включать все слова в точный запрос).

stocks: Если Вы начинаете запрос с stocks: Гугл обработает остальную часть сроков запроса как символы биржевых сводок, и свяжется со страницей, показывающую готовую информацию для этих символов.
Например, stocks: Intel yahoo покажет информацию о Intel и Yahoo. (Отметьте, что Вы должны напечатать символы последних новостей, не название компании)

Модификаторы Запросов

site: Если Вы включаете site: в ваш запрос, Гугл ограничит результаты теми вебсайтами, которые найдет в данном домене.
Также можно искать и по отдельным зонам, как таковое ru, org, com, etc ( site:com site:ru )

allintitle: Если Вы запускаете запрос с allintitle:, Гугл ограничит результаты со всеми словами запроса в заголовке.
Например, allintitle: google search вернет все страницы гугла по поиску как то images, Blog, etc

intitle: Если Вы включаете intitle: в вашем запросе, Гугл ограничит результаты документами, содержащими то слово в заголовке.
Например, intitle:Бизнес

allinurl: Если Вы запускаете запрос с allinurl: Гугл ограничит результаты, со всеми словами запроса в URL.
Например, allinurl: google search вернет документы с google и search в заголовке. Также как вариант можно разделять слова слэшем (/) тогда слова по обе стороны слэша будут искаться в пределах одной страницы: Пример allinurl: foo/bar

inurl: Если Вы включаете inurl: в вашем запросе, Гугл ограничит результаты документами, содержащими то слово в URL.
Например, Animation inurl:сайт

intext: ищет только в тексте страницы указанное слово, игнорируя заглавие и тексты ссылок, и прочее не относящееся к. Есть также и производная этого модификатора - allintext: т.е. далее все слова в запросе будут искаться только в тексте, что тоже бывает важно, игнорируя часто используемые слова в ссылках
Например, intext:форум

daterange: ищет во временных рамках (daterange:2452389-2452389), даты для времени указываются в Юлианском формате.

Ну и еще всякие интересные примеры запросов

Примеры составления запросов для Google. Для спамеров

Inurl:control.guest?a=sign

Site:books.dreambook.com “Homepage URL” “Sign my” inurl:sign

Site:www.freegb.net Homepage

Inurl:sign.asp “Character Count”

“Message:” inurl:sign.cfm “Sender:”

Inurl:register.php “User Registration” “Website”

Inurl:edu/guestbook “Sign the Guestbook”

Inurl:post “Post Comment” “URL”

Inurl:/archives/ “Comments:” “Remember info?”

“Script and Guestbook Created by:” “URL:” “Comments:”

Inurl:?action=add “phpBook” “URL”

Intitle:”Submit New Story”

Журналы

Inurl:www.livejournal.com/users/ mode=reply

Inurl greatestjournal.com/ mode=reply

Inurl:fastbb.ru/re.pl?

Inurl:fastbb.ru /re.pl? “Гостевая книга

Блоги

Inurl:blogger.com/comment.g?”postID”"anonymous”

Inurl:typepad.com/ “Post a comment” “Remember personal info?”

Inurl:greatestjournal.com/community/ “Post comment” “addresses of anonymous posters”

“Post comment” “addresses of anonymous posters” -

Intitle:”Post comment”

Inurl:pirillo.com “Post comment”

Форумы

Inurl:gate.html?”name=Forums” “mode=reply”

Inurl:”forum/posting.php?mode=reply”

Inurl:”mes.php?”

Inurl:”members.html”

Inurl:forum/memberlist.php?”

cURL - это специальный инструмент, который предназначен для того, чтобы передавать файлы и данные синтаксисом URL. Данная технология поддерживает множество протоколов, таких как HTTP, FTP, TELNET и многие другие. Изначально cURL было разработано для того, чтобы быть инструментом командной строки. К счастью для нас, библиотека cURL поддерживается языком программирования PHP. В этой статье мы рассмотрим некоторые расширенные функций cURL, а также затронем практическое применение полученных знаний средствами PHP.

Почему cURL?

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

$content = file_get_contents("http://www.nettuts.com"); // или $lines = file("http://www.nettuts.com"); // или readfile("http://www.nettuts.com");

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

cURL - это мощная библиотека, которая поддерживает множество различных протоколов, опций и обеспечивает подробную информацию о URL запросах.

Базовая структура

  • Инициализация
  • Назначение параметров
  • Выполнение и выборка результата
  • Освобождение памяти

// 1. инициализация $ch = curl_init(); // 2. указываем параметры, включая url curl_setopt($ch, CURLOPT_URL, "http://www.nettuts.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); // 3. получаем HTML в качестве результата $output = curl_exec($ch); // 4. закрываем соединение curl_close($ch);

Шаг #2 (то есть, вызов curl_setopt()) будем обсуждать в этой статье намного больше, чем все другие этапы, т.к. на этой стадии происходит всё самое интересное и полезное, что вам необходимо знать. В cURL существует огромное количество различных опций, которые должны быть указаны, для того чтобы иметь возможность сконфигурировать URL-запрос самым тщательным образом. Мы не будем рассматривать весь список целиком, а остановимся только на том, что я посчитаю нужным и полезным для этого урока. Всё остальное вы сможете изучить сами, если эта тема вас заинтересует.

Проверка Ошибки

Вдобавок, вы также можете использовать условные операторы для проверки выполнения операции на успех:

// ... $output = curl_exec($ch); if ($output === FALSE) { echo "cURL Error: " . curl_error($ch); } // ...

Тут прошу отметить для себя очень важный момент: мы должны использовать “=== false” для сравнения, вместо “== false”. Для тех, кто не в курсе, это поможет нам отличать пустой результат от булевого значения false, которое и будет указывать на ошибку.

Получение информации

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

// ... curl_exec($ch); $info = curl_getinfo($ch); echo "Took " . $info["total_time"] . " seconds for url " . $info["url"]; // …

Возвращаемый массив содержит следующую информацию:

  • “url”
  • “content_type”
  • “http_code”
  • “header_size”
  • “request_size”
  • “filetime”
  • “ssl_verify_result”
  • “redirect_count”
  • “total_time”
  • “namelookup_time”
  • “connect_time”
  • “pretransfer_time”
  • “size_upload”
  • “size_download”
  • “speed_download”
  • “speed_upload”
  • “download_content_length”
  • “upload_content_length”
  • “starttransfer_time”
  • “redirect_time”

Обнаружение перенаправления в зависимости от браузера

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

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

// тестируем URL $urls = array("http://www.cnn.com", "http://www.mozilla.com", "http://www.facebook.com"); // тестируем браузеры $browsers = array("standard" => array ("user_agent" => "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729)", "language" => "en-us,en;q=0.5"), "iphone" => array ("user_agent" => "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A537a Safari/419.3", "language" => "en"), "french" => array ("user_agent" => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB6; .NET CLR 2.0.50727)", "language" => "fr,fr-FR;q=0.5")); foreach ($urls as $url) { echo "URL: $url\n"; foreach ($browsers as $test_name => $browser) { $ch = curl_init(); // указываем url curl_setopt($ch, CURLOPT_URL, $url); // указываем заголовки для браузера curl_setopt($ch, CURLOPT_HTTPHEADER, array("User-Agent: {$browser["user_agent"]}", "Accept-Language: {$browser["language"]}")); // нам не нужно содержание страницы curl_setopt($ch, CURLOPT_NOBODY, 1); // нам необходимо получить HTTP заголовки curl_setopt($ch, CURLOPT_HEADER, 1); // возвращаем результаты вместо вывода curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); // был ли HTTP редирект? if (preg_match("!Location: (.*)!", $output, $matches)) { echo "$test_name: redirects to $matches\n"; } else { echo "$test_name: no redirection\n"; } } echo "\n\n"; }

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

Приём, который мы используем в этом примере для того, чтобы задать настройки cURL, позволит нам получить не содержание страницы, а только HTTP-заголовки (сохраненные в $output). Далее, воспользовавшись простым regex, мы можем определить, присутствовала ли строка “Location:” в полученных заголовках.

Когда вы запустите данный код, то должны будете получить примерно следующий результат:

Создание POST запроса на определённый URL

При формировании GET запроса передаваемые данные могут быть переданы на URL через “строку запроса”. Например, когда Вы делаете поиск в Google, критерий поиска располагаются в адресной строке нового URL:

Http://www.google.com/search?q=ruseller

Для того чтобы сымитировать данный запрос, вам не нужно пользоваться средствами cURL. Если лень вас одолевает окончательно, воспользуйтесь функцией “file_get_contents()”, для того чтобы получить результат.

Но дело в том, что некоторые HTML-формы отправляют POST запросы. Данные этих форм транспортируются через тело HTTP запроса, а не как в предыдущем случае. Например, если вы заполнили форму на форуме и нажали на кнопку поиска, то скорее всего будет совершён POST запрос:

Http://codeigniter.com/forums/do_search/

Мы можем написать PHP скрипт, который может сымитировать этот вид URL запроса. Сначала давайте создадим простой файл для принятия и отображения POST данных. Назовём его post_output.php:

Print_r($_POST);

Затем мы создаем PHP скрипт, чтобы выполнить cURL запрос:

$url = "http://localhost/post_output.php"; $post_data = array ("foo" => "bar", "query" => "Nettuts", "action" => "Submit"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // указываем, что у нас POST запрос curl_setopt($ch, CURLOPT_POST, 1); // добавляем переменные curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $output = curl_exec($ch); curl_close($ch); echo $output;

При запуске данного скрипта вы должны получить подобный результат:

Таким образом, POST запрос был отправлен скрипту post_output.php, который в свою очередь, вывел суперглобальный массив $_POST, содержание которого мы получили при помощи cURL.

Загрузка файла

Сначала давайте создадим файл для того, чтобы сформировать его и отправить файлу upload_output.php:

Print_r($_FILES);

А вот и код скрипта, который выполняет указанный выше функционал:

$url = "http://localhost/upload_output.php"; $post_data = array ("foo" => "bar", // файл, который необходимо загрузить "upload" => "@C:/wamp/www/test.zip"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $output = curl_exec($ch); curl_close($ch); echo $output;

Когда вы хотите загрузить файл, все, что вам нужно сделать, так это передать его как обычную post переменную, предварительно поместив перед ней символ @. При запуске написанного скрипта вы получите следующий результат:

Множественный cURL

Одной из самых сильных сторон cURL является возможность создания "множественных" cURL обработчиков. Это позволяет вам открывать соединение к множеству URL одновременно и асинхронно.

В классическом варианте cURL запроса выполнение скрипта приостанавливается, и происходит ожидание завершения операции URL запроса, после чего работа скрипта может продолжиться. Если вы намереваетесь взаимодействовать с целым множеством URL, это приведёт к довольно-таки значительным затратам времени, поскольку в классическом варианте вы можете работать только с одним URL за один раз. Однако, мы можем исправить данную ситуацию, воспользовавшись специальными обработчиками.

Давайте рассмотрим пример кода, который я взял с php.net:

// создаём несколько cURL ресурсов $ch1 = curl_init(); $ch2 = curl_init(); // указываем URL и другие параметры curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/"); curl_setopt($ch1, CURLOPT_HEADER, 0); curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/"); curl_setopt($ch2, CURLOPT_HEADER, 0); //создаём множественный cURL обработчик $mh = curl_multi_init(); //добавляем несколько обработчиков curl_multi_add_handle($mh,$ch1); curl_multi_add_handle($mh,$ch2); $active = null; //выполнение do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active && $mrc == CURLM_OK) { if (curl_multi_select($mh) != -1) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } //закрытие curl_multi_remove_handle($mh, $ch1); curl_multi_remove_handle($mh, $ch2); curl_multi_close($mh);

Идея состоит в том, что вы можете использовать множественные cURL обработчики. Используя простой цикл, вы можете отследить, какие запросы ещё не выполнились.

В этом примере есть два основных цикла. Первый цикл do-while вызывает функцию curl_multi_exec(). Эта функция не блокируемая. Она выполняется с той скоростью, с которой может, и возвращает состояние запроса. Пока возвращенное значение является константой ‘CURLM_CALL_MULTI_PERFORM’, это означает, что работа ещё не завершена (например, в данный момент происходит отправка http заголовков в URL); Именно поэтому мы продолжаем проверять это возвращаемое значение, пока не получим другой результат.

В следующем цикле мы проверяем условие, пока переменная $active = "true". Она является вторым параметром для функции curl_multi_exec(). Значение данной переменной будет равно "true", до тех пор, пока какое-то из существующих изменений является активным. Далее мы вызываем функцию curl_multi_select(). Её выполнение "блокируется", пока существует хоть одно активное соединение, до тех пор, пока не будет получен ответ. Когда это произойдёт, мы возвращаемся в основной цикл, чтобы продолжить выполнение запросов.

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

Проверяем ссылки в WordPress

Представьте себе блог с огромным количеством постов и сообщений, в каждом из которых есть ссылки на внешние интернет ресурсы. Некоторые из этих ссылок по различным причинам могли бы уже быть «мертвыми». Возможно, страница была удалена или сайт вовсе не работает.

Мы собираемся создать скрипт, который проанализирует все ссылки и найдёт незагружающиеся веб-сайты и страницы 404, после чего предоставит нам подробнейший отчёт.

Сразу же скажу, что это не пример создания плагина для WordPress. Это всего на всего хороший полигон для наших испытаний.

Давайте же наконец начнём. Сначала мы должны сделать выборку всех ссылок из базы данных:

// конфигурация $db_host = "localhost"; $db_user = "root"; $db_pass = ""; $db_name = "wordpress"; $excluded_domains = array("localhost", "www.mydomain.com"); $max_connections = 10; // инициализация переменных $url_list = array(); $working_urls = array(); $dead_urls = array(); $not_found_urls = array(); $active = null; // подключаемся к MySQL if (!mysql_connect($db_host, $db_user, $db_pass)) { die("Could not connect: " . mysql_error()); } if (!mysql_select_db($db_name)) { die("Could not select db: " . mysql_error()); } // выбираем все опубликованные посты, где есть ссылки $q = "SELECT post_content FROM wp_posts WHERE post_content LIKE "%href=%" AND post_status = "publish" AND post_type = "post""; $r = mysql_query($q) or die(mysql_error()); while ($d = mysql_fetch_assoc($r)) { // делаем выборку ссылок при помощи регулярных выражений if (preg_match_all("!href=\"(.*?)\"!", $d["post_content"], $matches)) { foreach ($matches as $url) { $tmp = parse_url($url); if (in_array($tmp["host"], $excluded_domains)) { continue; } $url_list = $url; } } } // убираем дубликаты $url_list = array_values(array_unique($url_list)); if (!$url_list) { die("No URL to check"); }

Сначала мы формируем конфигурационные данные для взаимодействия с базой данных, далее пишем список доменов, которые не будут участвовать в проверке ($excluded_domains). Также мы определяем число, характеризующее количество максимальных одновременных соединений, которые мы будем использовать в нашем скрипте ($max_connections). Затем мы присоединяемся к базе данных, выбираем посты, которые содержат ссылки, и накапливаем их в массив ($url_list).

Следующий код немного сложен, так что разберитесь в нём от начала до конца:

// 1. множественный обработчик $mh = curl_multi_init(); // 2. добавляем множество URL for ($i = 0; $i < $max_connections; $i++) { add_url_to_multi_handle($mh, $url_list); } // 3. инициализация выполнения do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); // 4. основной цикл while ($active && $mrc == CURLM_OK) { // 5. если всё прошло успешно if (curl_multi_select($mh) != -1) { // 6. делаем дело do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); // 7. если есть инфа? if ($mhinfo = curl_multi_info_read($mh)) { // это значит, что запрос завершился // 8. извлекаем инфу $chinfo = curl_getinfo($mhinfo["handle"]); // 9. мёртвая ссылка? if (!$chinfo["http_code"]) { $dead_urls = $chinfo["url"]; // 10. 404? } else if ($chinfo["http_code"] == 404) { $not_found_urls = $chinfo["url"]; // 11. рабочая } else { $working_urls = $chinfo["url"]; } // 12. чистим за собой curl_multi_remove_handle($mh, $mhinfo["handle"]); // в случае зацикливания, закомментируйте данный вызов curl_close($mhinfo["handle"]); // 13. добавляем новый url и продолжаем работу if (add_url_to_multi_handle($mh, $url_list)) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } } } // 14. завершение curl_multi_close($mh); echo "==Dead URLs==\n"; echo implode("\n",$dead_urls) . "\n\n"; echo "==404 URLs==\n"; echo implode("\n",$not_found_urls) . "\n\n"; echo "==Working URLs==\n"; echo implode("\n",$working_urls); function add_url_to_multi_handle($mh, $url_list) { static $index = 0; // если у нас есть ещё url, которые нужно достать if ($url_list[$index]) { // новый curl обработчик $ch = curl_init(); // указываем url curl_setopt($ch, CURLOPT_URL, $url_list[$index]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_NOBODY, 1); curl_multi_add_handle($mh, $ch); // переходим на следующий url $index++; return true; } else { // добавление новых URL завершено return false; } }

Тут я попытаюсь изложить всё по полочкам. Числа в списке соответствуют числам в комментарии.

  1. 1. Создаём множественный обработчик;
  2. 2. Функцию add_url_to_multi_handle() мы напишем чуть позже. Каждый раз, когда она будет вызываться, начнётся обработка нового url. Первоначально, мы добавляем 10 ($max_connections) URL;
  3. 3. Для того чтобы начать работу, мы должны запустить функцию curl_multi_exec(). До тех пор, пока она будет возвращать CURLM_CALL_MULTI_PERFORM, нам ещё есть, что делать. Это нам нужно, главным образом, для того, чтобы создать соединения;
  4. 4. Далее следует основной цикл, который будет выполняться до тех пор, пока у нас есть хоть одно активное соединение;
  5. 5. curl_multi_select() зависает в ожидании, пока поиск URL не завершится;
  6. 6. И снова мы должны заставить cURL выполнить некоторую работу, а именно, сделать выборку данных возвращаемого ответа;
  7. 7. Тут происходит проверка информации. В результате выполнения запроса будет возвращён массив;
  8. 8. В возвращенном массиве присутствует cURL обработчик. Его мы и будем использовать для того, чтобы выбрать информацию об отдельном cURL запросе;
  9. 9. Если ссылка была мертва, или время выполнения скрипта вышло, то нам не следует искать никакого http кода;
  10. 10. Если ссылка возвратила нам страницу 404, то http код будет содержать значение 404;
  11. 11. В противном случае, перед нами находится рабочая ссылка. (Вы можете добавить дополнительные проверки на код ошибки 500 и т.д...);
  12. 12. Далее мы удаляем cURL обработчик, потому что больше в нём не нуждаемся;
  13. 13. Теперь мы можем добавить другой url и запустить всё то, о чём говорили до этого;
  14. 14. На этом шаге скрипт завершает свою работу. Мы можем удалить всё, что нам не нужно и сформировать отчет;
  15. 15. В конце концов, напишем функцию, которая будет добавлять url в обработчик. Статическая переменная $index будет увеличиваться каждый раз, когда данная функция будет вызвана.

Я использовал данный скрипт на своем блоге (с некоторыми неработающими ссылками, которые добавил нарочно для того, чтобы протестировать его работу) и получил следующий результат:

В моём случае, скрипту потребовалось чуть меньше чем 2 секунды, чтобы пробежаться по 40 URL. Увеличение производительности является существенным при работе с еще большим количеством URL адресов. Если вы открываете десять соединений одновременно, то скрипт может выполниться в десять раз быстрее.

Пару слов о других полезных опциях cURL

HTTP Аутентификация

Если на URL адресе есть HTTP аутентификация, то вы без труда можете воспользоваться следующим скриптом:

$url = "http://www.somesite.com/members/"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // указываем имя и пароль curl_setopt($ch, CURLOPT_USERPWD, "myusername:mypassword"); // если перенаправление разрешено curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // то сохраним наши данные в cURL curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1); $output = curl_exec($ch); curl_close($ch);

FTP загрузка

В PHP также существует библиотека для работы с FTP, но вам ничего не мешает и тут воспользоваться средствами cURL:

// открываем файл $file = fopen("/path/to/file", "r"); // в url должно быть следующее содержание $url = "ftp://username:[email protected]:21/path/to/new/file"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_UPLOAD, 1); curl_setopt($ch, CURLOPT_INFILE, $fp); curl_setopt($ch, CURLOPT_INFILESIZE, filesize("/path/to/file")); // указывам ASCII мод curl_setopt($ch, CURLOPT_FTPASCII, 1); $output = curl_exec($ch); curl_close($ch);

Используем Прокси

Вы можете выполнить свой URL запрос через прокси:

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://www.example.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // указываем адрес curl_setopt($ch, CURLOPT_PROXY, "11.11.11.11:8080"); // если необходимо предоставить имя пользователя и пароль curl_setopt($ch, CURLOPT_PROXYUSERPWD,"user:pass"); $output = curl_exec($ch); curl_close ($ch);

Функции обратного вызова

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

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://net.tutsplus.com"); curl_setopt($ch, CURLOPT_WRITEFUNCTION,"progress_function"); curl_exec($ch); curl_close ($ch); function progress_function($ch,$str) { echo $str; return strlen($str); }

Подобная функция ДОЛЖНА возвращать длину строки, что является обязательным требованием.

Заключение

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

Спасибо! Удачного дня!

Эту статью давно стоило переписать (слишком много «экономии на спичках»), но руки не доходят. Пускай весит и напоминает о том, как мы глупы в молодости.
Одним из основных критериев успешности любого интернет-ресурса является скорость его работы и с каждым годом пользователи становятся всё более и более требовательными по этому критерию. Оптимизация работы php-скиптов - это один из методов обеспечения скорости работы системы.
В этой статье я бы хотел представить на суд общественности свой сборник советов и фактов по оптимизации скриптов. Сборник собирался мною достаточно долго, основан на нескольких источниках и личных экспериментах.
Почему сборник советов и фактов, а не жестких правил? Потому что, как я убедился, не существует «абсолютно правильной оптимизации». Многие приёмы и правила противоречивы и выполнить их все невозможно. Приходиться выбирать совокупность методов, которыми приемлемо пользоваться без ущерба безопасности и удобности. Я занял рекомендательную позицию и поэтому у меня советы и факты, которые Вы можете соблюдать, а можете и не соблюдать.
Что бы не было путаницы, я разделил все советы и факты на 3 группы:

  • Оптимизация кода
  • Бесполезная оптимизация
Группы выделены условно и некоторые пункты можно отнести сразу к нескольким из них. Цифры приведены для среднестатистического сервера (LAMP). В статье не рассматриваются вопросы связанные с эффективностью различных сторонних технологий и фреймворков, так как это тема отдельных дискуссий.

Оптимизация на уровне логики и организации приложения

Многие из советов и фактов, относящихся к данной группе оптимизации, являются весьма значимыми и дают весьма большой выигрыш во времени.
  • Постоянно профилируйте свой код на сервере (xdebug) и на клиенте (firebug), что бы выявить узкие места кода
    Следует отметить, что профилировать надо и серверную, и клиентскую часть, так как не все серверные ошибки можно обнаружить на самом сервере.
  • Количество, используемых в программе пользовательских функций, никак не влияет на скорость
    Это позволяет использовать в программе бесчисленное число пользовательских функций.
  • Активно используйте пользовательские функций
    Положительный эффект достигается за счёт того, что внутри функций операции ведутся только с локальными переменными. Эффект этого больше, чем расходы на вызовы пользовательских функций.
  • «Критически тяжёлые» функции желательно реализовать на стороннем языка программирования в виде расширения PHP
    Это требует навыков программирования на стороннем языке, что значительно увеличивает время разработки, но в тоже время позволяет использовать приёмы вне возможности PHP.
  • Обработка статического файла html быстрее, чем интерпретируемого файла php
    Различие повремени на клиенте может составлять около 1 секунды, поэтому имеет смысл четкое разделение статики и генерируемых средствами PHP страниц.
  • Размер обрабатываемого (подключаемого) файла влияет на скорость
    Примерно на обработку каждых 2 Кб тратиться 0.001 секунды. Этот факт толкает нас на проведение минимизации кода скриптов при перенесении на рабочий сервер.
  • Старайтесь не использовать постоянно require_once или include_once
    Эти функции нужно использовать при наличии возможности повторного считывания файла, в остальных случаях желательно использовать require и include .
  • При ветвлении алгоритма, если имеются конструкции, которые могут не обрабатываться и их объём порядка 4 Кб и более, то более оптимально их подключать при помощи include.
  • Желательно использовать проверку отправляемых данных на клиенте
    Это вызвано тем, что при проверке данных на стороне клиента, резко снижается количество запросов с неверными данными. Системы проверки данных на клиенте строятся в основном с использованием JS и жестких элементов формы (select).
  • Желательно большие конструкций DOM для массивов данных строить на клиенте
    Это очень эффективный метод оптимизации при работе с отображением большого объёма данных. Суть его сводится к следующему: на сервере подготавливается массив данных и передаётся клиенту, а построение конструкций DOM предоставляется JS функциям. В результате нагрузка частично перераспределяется с сервера на клиент.
  • Системы, построенные на технологии AJAX, значительно быстрее, чем системы, не использующие эту технологию
    Это вызвано уменьшением объёмов вывода и перераспределением нагрузки на клиента. На практике скорость систем с AJAX в 2-3 раза выше. Замечание: AJAX в свою очередь создаёт ряд ограничений на использование других методов оптимизации, например, работа с буфером.
  • При получение post-запроса всегда возвращайте что-нибудь, можно даже пробел
    Иначе клиенту будет отправлена страница ошибки, которая весит несколько килобайт. Данная ошибка очень часто встречается в системах, использующих технологию AJAX.
  • Получение данных из файла быстрее, чем из БД
    Это во многом вызвано затратами на подключение к БД. К моему удивлению, огромный процент программистов маниакально хранят все данные в БД, даже когда использование файлов быстрее и удобнее. Замечание: в файлах можно хранить данные, по которым не ведётся поиск, в противном случае следует использовать БД.
  • Не осуществляйте подключение к БД без необходимости
    По неизвестной мне причине, многие программисты осуществляют подключение к БД на этапе считывания настроек, хотя далее они могут не делать запросов к БД. Это вредная привычка, которая стоит в среднем 0.002 секунды.
  • Используйте постоянное соединение с БД при малом количестве одновременно активных клиентов
    Выгода во времени вызвана отсутствием затрат на подключение к БД. Разница во времени примерно 0.002 секунды. Замечание: при большом количестве пользователей постоянные соединения использовать нежелательно. При работе с постоянными соединениями должен быть механизм завершения соединений.
  • Использование сложных запросов к БД быстрее, чем использование нескольких простых
    Разница во времени зависит от многих факторов (объём данных, настройка БД и пр.) и измеряется тысячными, а иногда даже сотыми, секунды.
  • Использование вычислений на стороне СУБД быстрее, чем вычисления на стороне PHP для данных хранящихся в БД
    Это вызвано тем фактором, что для таких вычислений на стороне PHP требуется два запроса к БД (получение и изменение данных). Разница во времени зависит от многих факторов (объём данных, настройка БД и пр.) и измеряется тысячными и сотыми секунды.
  • Если данные выборки из БД редко меняются и к этим данным обращается множество пользователей, то имеет смысл сохранить данные выборки в файл
    Например можно использовать следующий простой подход: получаем данные выборки из БД и сохраняем их как сериализованный массив в файл, далее любой пользователь использует данные из файла. На практике такой метод оптимизации может дать многократный прирост скорости выполнения скрипта. Замечание: При использовании данного метода требуются писать инструменты для формирования и изменения данных хранимых файле.
  • Кэшируйте данные, которые редко меняются, при помощи memcached
    Выигрыш времени может быть весьма значительным. Замечание: кэширование эффективно для статичных данных, для динамичных данных эффект снижается и может быть отрицательным.
  • Работа без объектов (без ООП) быстрее, чем работа с использованием объектов, примерно, в три раза
    Памяти «съедается» также больше. К сожалению, интерпретатор PHP не может работать с ООП также быстро как с обычными функциями.
  • Чем больше мерность массивов, тем медленнее они работают
    Потеря времени возникает из-за обработки вложенности структур.

Оптимизация кода

Данные советы и факты дают незначительны по сравнению с предыдущей группой прирост скорости, но в своей совокупности эти приёмы могут дать неплохой выигрыш времени.
  • echo и print значительно быстрее, чем printf
    Разница во времени может доходить до нескольких тысячных секунды. Это вызвано тем, что printf служит для вывода форматированных данных и интерпретатор проверяет полностью строку на вхождение таких данных. printf используется только для вывода данных, которым нужно форматирование.
  • echo $var."text" быстрее, чем echo "$var text"
    Это вызвано тем, что движок PHP во втором случае вынужден искать переменные внутри строки. Для больших объёмов данных и старых версий PHP различия по времени заметны.
  • echo "a" быстрее, чем echo "a" для строк без переменных
    Это вызвано тем, что во втором случае движок PHP пытается найти переменные. Для больших объёмов данных различия во времени достаточно заметны.
  • echo "a","b" быстрее, чем echo "a"."b"
    Вывод данных через запятую быстрее, чем через точку. Это вызвано тем, что во втором случае происходит конкатенация строк. Для больших объёмов данных различия во времени достаточно заметны. Примечание: это работает только с функцией echo, которая может принимать несколько строк в качестве аргументов.
  • $return="a"; $return.="b"; echo $return; быстрее, чем echo "a"; echo "b";
    Причина в том, что вывод данных требует некоторых дополнительных операций. Для больших объёмов данных различия во времени достаточно заметны.
  • ob_start(); echo "a"; echo "b"; ob_end_flush(); быстрее, чем $return="a"; $return.="b"; echo $return;
    Это вызвано тем, что вся работа осуществляется без обращения к переменным. Для больших объёмов данных различия во времени достаточно заметны. Замечание: данный прием неэффективен, если вы работаете с AJAX, так как в этом случае данные желательно возвращать в виде одной строки.
  • Используйте «профессиональную вставку» или?> a b
    Статические данные (вне программного кода) обрабатываются быстрее, чем вывод данных PHP. Этот прием называется профессиональной вставкой. Для больших объёмов данных различия во времени достаточно заметны.
  • readfile быстрее, чем file_get_contents , file_get_contents быстрее, чем require , а require быстрее, чем include для вывода статического контента из отдельного файла
    По времени считывания пустого файла колебания от 0.001 для readfile до 0.002 для include .
  • require быстрее, чем include для интерпретируемых файлов
    Замечание: при ветвлении алгоритма, когда есть возможность не использовать интерпретируемый файл, надо использовать include , т.к. require подключает файл всегда.
  • if (...) {...} else if (...) {} быстрее, чем switch
    Время зависит от количества веток.
  • if (...) {...} else if (...) {} быстрее, чем if (...) {...}; if (...) {};
    Время зависит от количества веток и условий. Необходимо использовать else if везде, где это возможно, так как это самая быстрая «условная» конструкция.
  • Наиболее часто встречающиеся условия конструкции if (...) {...} else if (...) {} надо помещать в начале ветвления
    Интерпритатор просматривает конструкцию сверху вниз, пока не найдет выполнение условия. Если интерпретатор находит выполнение условия, то остальныю часть конструкции он не просматривает.
  • < x; ++$i) {...} быстрее, чем for($i = 0; $i < sizeOf($array); ++$i) {...}
    Это вызвано тем, что во втором случае операция sizeOf будет выполнятся при каждой итерации. Время разницы выполнения зависит от числа элементов массива.
  • x = sizeOf($array); for($i = 0; $i < x; ++$i) {...} быстрее, чем foreach($arr as $value) {...} для не ассоциативных массивов
    Разница во времени значительна и увеличивается при увеличении массива.
  • preg _replace быстрее, чем ereg_replace , str_replace быстрее, чем preg_replace , но strtr быстрее, чем str_replace
    Разница во времени зависит от объёма данных и может достигать нескольких тысячных секунд.
  • Функции работы со строками быстрее, чем регулярные выражения
    Это правило является следствием предыдущего.
  • Удаляйте уже ненужные переменные-массивы для освобождения памяти.
  • Старайтесь не использовать подавление ошибок @
    Подавление ошибок производит ряд очень медленных операций, а так как частота повтора может быть очень большой, потери скорости могут быть значительными.
  • if (isset($str{5})) {...} быстрее, чем if (strlen($str)>4){...}
    Это вызвано тем, что вместо функции для работы со строками strlen используется стандартная операция проверки isset .
  • 0.5 быстрее, чем 1/2
    Причина в том, что во втором случае выполняется операция деления.
  • return быстрее, чем global при возвращении значения переменной из функции
    Это вызвано тем, что во втором случае создаётся глобальная переменная.
  • $row["id"] быстрее, чем $row
    Первый вариант быстрее в 7 раз.
  • $_SERVER[’REQUEST_TIME’] быстрее, чем time() для определения времени запуска скрипта
  • if ($var===null) {...} быстрее, чем if (is_null($var)) {...}
    Причина в том, что в первом случае нет использования функции.
  • ++i быстрее, чем i++ , --i быстрее, чем i--
    Это вызвано особенностями ядра PHP. Разница по времени менее 0.000001, но если у Вас данные процедуры повторяются тысячи раз, то присмотритесь к данной оптимизации.
  • Инкремент инициализированной переменой i=0; ++i; быстрее, чем не инициализированной ++i
    Разница по времени около 0.000001 секунды, но из-за возможной частоты повтора следует помнить данный факт.
  • Использование «отработавших» переменных быстрее, чем объявление новых
    Или перефразирую иначе – Не создавайте лишних переменных.
  • Работа с локальными переменными быстрее, чем с глобальными, примерно, в 2 раза
    Хоть и разница во времени менее 0.000001 секунды, но из-за высокой частоты повторения следует стараться работать с локальными переменными.
  • Обращение к переменной напрямую быстрее, чем вызов функции, внутри которой определяется эта переменная в несколько раз
    На вызов функции тратиться примерно в три раза больше времени, чем на вызов переменной.

Бесполезная оптимизация

Ряд методов оптимизации на практике не оказывают большого влияния на скорость выполнения скриптов (выигрыш времени менее 0.000001 секунды). Несмотря на это, такая оптимизация зачастую становиться предметом споров. Я привел данные «бесполезные» факты для того, чтобы вы в последующим не уделяли им особого внимания при написании кода.
  • echo быстрее, чем print
  • include("абсолютный путь") быстрее, чем include("относительный путь")
  • sizeOf быстрее, чем count
  • foreach ($arr as $key => $value) {...} быстрее, чем reset ($arr); while (list($key, $value) = each ($arr)) {...} для ассоциативных массивов
  • Не комментированный код быстрее, чем комментированный, так как уходит дополнительное время на чтение файла
    Весьма глупо уменьшать объём комментариев ради оптимизации, надо просто в рабочих («боевых») скриптах проводить минимизацию.
  • Переменные с короткими названиями быстрее, чем переменные с длинными названиями
    Это вызвано сокращением объёмов обрабатываемого кода. Аналогично предыдущему пункту, надо просто в рабочих («боевых») скриптах проводить минимизацию.
  • Разметка кода с использованием табуляции быстрее, чем с использованием пробелов
    Аналогично предыдущему пункту.
Напоследок, хочу раз напомнить, что приведённые мною советы и факты не абсолютны и значимость их применения зависит от конкретной ситуации. Необходимо помнить, что оптимизация скриптов лишь малая часть от всей процедуры оптимизации и зачастую возможно спокойно жить без вышеописанных советов.

Для написания статьи частично пользовались материалы.

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

Inurl:pageid= inurl:games.php?id= inurl:page.php?file= inurl:newsDetail.php?id= inurl:gallery.php?id= inurl:article.php?id= inurl:show.php?id= inurl:staff_id= inurl:newsitem.php?num= inurl:readnews.php?id= inurl:top10.php?cat= inurl:historialeer.php?num= inurl:reagir.php?num= inurl:Stray-Questions-View.php?num= inurl:forum_bds.php?num= inurl:game.php?id= inurl:view_product.php?id= inurl:newsone.php?id= inurl:sw_comment.php?id= inurl:news.php?id= inurl:avd_start.php?avd= inurl:event.php?id= inurl:product-item.php?id= inurl:sql.php?id= inurl:news_view.php?id= inurl:select_biblio.php?id= inurl:humor.php?id= inurl:aboutbook.php?id= inurl:ogl_inet.php?ogl_id= inurl:fiche_spectacle.php?id= inurl:communique_detail.php?id= inurl:sem.php3?id= inurl:kategorie.php4?id= inurl:news.php?id= inurl:index.php?id= inurl:faq2.php?id= inurl:show_an.php?id= inurl:preview.php?id= inurl:loadpsb.php?id= inurl:opinions.php?id= inurl:spr.php?id= inurl:pages.php?id= inurl:announce.php?id= inurl:clanek.php4?id= inurl:participant.php?id= inurl:download.php?id= inurl:main.php?id= inurl:review.php?id= inurl:chappies.php?id= inurl:read.php?id= inurl:prod_detail.php?id= inurl:viewphoto.php?id= inurl:article.php?id= inurl:person.php?id= inurl:productinfo.php?id= inurl:showimg.php?id= inurl:view.php?id= inurl:website.php?id= inurl:hosting_info.php?id= inurl:gallery.php?id= inurl:rub.php?idr= inurl:view_faq.php?id= inurl:artikelinfo.php?id= inurl:detail.php?ID= inurl:index.php?= inurl:profile_view.php?id= inurl:category.php?id= inurl:publications.php?id= inurl:fellows.php?id= inurl:downloads_info.php?id= inurl:prod_info.php?id= inurl:shop.php?do=part&id= inurl:productinfo.php?id= inurl:collectionitem.php?id= inurl:band_info.php?id= inurl:product.php?id= inurl:releases.php?id= inurl:ray.php?id= inurl:produit.php?id= inurl:pop.php?id= inurl:shopping.php?id= inurl:productdetail.php?id= inurl:post.php?id= inurl:viewshowdetail.php?id= inurl:clubpage.php?id= inurl:memberInfo.php?id= inurl:section.php?id= inurl:theme.php?id= inurl:page.php?id= inurl:shredder-categories.php?id= inurl:tradeCategory.php?id= inurl:product_ranges_view.php?ID= inurl:shop_category.php?id= inurl:transcript.php?id= inurl:channel_id= inurl:item_id= inurl:newsid= inurl:trainers.php?id= inurl:news-full.php?id= inurl:news_display.php?getid= inurl:index2.php?option= inurl:readnews.php?id= inurl:top10.php?cat= inurl:newsone.php?id= inurl:event.php?id= inurl:product-item.php?id= inurl:sql.php?id= inurl:aboutbook.php?id= inurl:preview.php?id= inurl:loadpsb.php?id= inurl:pages.php?id= inurl:material.php?id= inurl:clanek.php4?id= inurl:announce.php?id= inurl:chappies.php?id= inurl:read.php?id= inurl:viewapp.php?id= inurl:viewphoto.php?id= inurl:rub.php?idr= inurl:galeri_info.php?l= inurl:review.php?id= inurl:iniziativa.php?in= inurl:curriculum.php?id= inurl:labels.php?id= inurl:story.php?id= inurl:look.php?ID= inurl:newsone.php?id= inurl:aboutbook.php?id= inurl:material.php?id= inurl:opinions.php?id= inurl:announce.php?id= inurl:rub.php?idr= inurl:galeri_info.php?l= inurl:tekst.php?idt= inurl:newscat.php?id= inurl:newsticker_info.php?idn= inurl:rubrika.php?idr= inurl:rubp.php?idr= inurl:offer.php?idf= inurl:art.php?idm= inurl:title.php?id= inurl:".php?id=1" inurl:".php?cat=1" inurl:".php?catid=1" inurl:".php?num=1" inurl:".php?bid=1" inurl:".php?pid=1" inurl:".php?nid=1"

вот небольшой списочек. Можете использовать свои. И так, мы нашли сайт. Например http://www.vestitambov.ru/
Далее качаем эту программу

**Hidden Content: To see this hidden content your post count must be 3 or greater.**

Жмем ОК. Затем вставляем сайт жертву.
Жмем старт. Далее ждем результатов.
И так, программа нашла SQL уязвимость.

Далее качаем Havij, http://www.vestitambov.ru:80/index.php?module=group_programs&id_gp= вставляем полученную ссылку туда. Объяснять как пользоваться Havij и где качать не буду, найти его не трудно. Все. Вы получили нужные вам данные - пароль администратора, а дальше дело уже вашей фантазии.

П.С. Это моя первая попытка что-то написать. Извиняюсь если что не так

mob_info