All streams
Search
Write a publication
Pull to refresh
30
0

PHP разработчик

Send message

я не специалист, но раз уж отливать собираетесь, то почему нельзя сделать форму, отлить в парафине, спилить лопасти и прилепить их нужной стороной и с этого уже отливать изделие?

По опыту сетчатая спинка затирает спину на футболках и кофтах до катышков, причем довольно быстро.
Из всех рюкзаков, с которыми приходилось иметь дело, больше всего понравился рюкзак с карманом «сзади», между спиной и лямками.
3 года хожу с недорогим
Promate Zest
image
image

В целом — супер, хотя на 3ий год начал подразваливаться.
Из плюсов — задний отдел под ноут, из которого что-нибудь украсть… ну такое себе, нужно через весь рюкзак прогрызаться и кармашек внизу спинки, в котором удобно носить телефон или кошелек. Легкий, вместительный и удобный, для города — самое то, для не дальних поездок — тоже сойдет.
Из минусов — спинка затирает одежду и оставляет катышки на кофтах/футболках, ноутбуки 15.6 влазят только если безрамочные, типичные больше 15 можно и не пытаться всунуть, на 3ий год начали сыпаться собачки змеек (металлическая часть переламывается внутри резинки).
С радостью взял бы такого же форм-фактора, но без сетчатой спинки. Хоть на заказ шей.
непосредственно кидаться по HTTP gzip или deflate из архива без распаковки для тех клиентов, что понимают.

Нет, все гораздо менее прозаично :)
Вообще вы описываете довольно редкий случай, как мне кажется — обычно много статики это картинки, музыка, видео и т.д., оно практически не жмется Deflate, ситуацию, когда у нас очень много статики, которую к тому же можно пожать я даже так не прикину на вскидку.
Так что сжатие тут не принципиально. А вот хранить например картинки, если их очень много, что инод не хватает — вполне вариант. Тем более архив не обязательно хранить у себя — вон в телеграме, например. А зная Range по которому лежит конкретный файл (архив-то мы ручками собирали, как не знать), мы можем выдать его пользователю не распаковывая архив, да. И если удалённый сервер поддерживает Partial Content, то прям оттуда. Или наоборот, мы можем хранить картинки в каком-нибудь твиттере, а на сервере только их crc32, длину и url, а пользователю отдавать архив, просто оборачивая те картинки в Zip заголовки.


Но меня интересует как, например, для 100МБ файла будут в таком случае обрабатываться Range запросы куска с середины.

В смысле если нам придет Range запрос? В случае этого скрипта — никак:) Но можно заморочиться, конечно.
Или как нам частично считать файл, чтоб отдать пользователю конкретный элемент из архива? Ну тут много вариантов, от банального fopen() + ftell() или file_get_contents() по смещению и раздавать из php или аналогично любым другим языком до финтов с nginx, например. Насчет nginx будет статья, скорее всего.

не ну само собой, что если нужно просто выдрать один атрибут или контент из тега, то регулярка сойдет.
но посмотрите на пример из поста — там же регексп будет длинней, чем оставшийся код на php:)
плюс DOM-парсеры более универсальное решение все же.
неужели городить регулярку проще, чем написать что-то в духе
(new Crawler($html))
    ->filter('.classname')
    ->first()
    ->attr('id')

да, в спешке набрасывал)

вот вы любите все усложнять:)
тут к чему ведут, так это что установка пакета композером нисколько не тяжелей скачивания библиотеки руками.
три строки а консоли (хоть в linux, хоть в каком-нибудь OpenServer под windows) и можно начинать накидывать код. даже если представить что у кого-то еще остался шаред хост, без консоли и вот этого вот всего, то вам же все равно закидывать туда проект по какому-нибудь ftp, так какая разница это папка vendor или phpQuery? и какая разница, будете ли вы писать require 'vendor/autoload.php' в своём скрипте или require 'phpQuery/phpQuery.php'?

mkdir myproject
cd myproject
wget https://getcomposer.org/composer.phar
php composer.phar require symfony/dom-crawler
php composer.phar require symfony/css-selector


если использовать phpquery его же тоже надо скачать, разархивировать, подключить.

phpQuery это просто обёртка для стандартной библиотеки DOM.

symfony/dom-crawler и symfony/css-selector — это два самобытных компонента, для жизни которых не нужна симфони. и вообще ничего не нужно, кроме стандартной DOM-библиотеки, на которой же и ваш phpQuery и основан.

phpQuery одна из самых легких для понимания.

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

есть symfony/dom-crawler, который враппер для стандартной DOM библиотеки. И с помощью symfony/css-selector можно писать в без XPath, оно само конвертирует.
Только вдобавок в отличии от phpQuery оно еще и написано не на статических свойствах, которые хранят хрен пойми, включая прошлые документы и не течет как соломенная крыша.

// Получаем код
$html = file_get_contents("https://какой-то_сайт.com/");

// Получаем объект dom
$dom = phpQuery::newDocument($html);

// Ищем в объекте dom элемент с классом .product-essential, обращаясь к методу find(). Он вмещает в себя все данные о продукте.
foreach($dom->find(".product-essential") as $key => $value){

        // Преобразуем dom объект в объект phpQuery. Делаем сие действие с помощью метода pq(); который является аналогом ($) в jQuery.
    $pq = pq($value);

    // Находим в этом элементе элемент с классом .brand-link и получаем значение атрибута "href" с помощью метода attr();
    $productHref[$key]["brand-href"] = $pq->find(".brand-link")->attr("href");

    // Получаем название бренда. Оно находится в строке <span class="brand-name">Какой-то бренд</span>.
    // Мы можем получить текст, содержащийся в <span> и других тегах с помощью метода text();
    $productHref[$key]["brand-name"] = $pq->find(".brand-name")->text();

    // Далее нам необходимо получить название товара.
    // Помимо указания класса элемента, мы можем указать имя вложенного элемента.
    // В данном случае имя бренда находится в элементе <h1>, который находится в элементе <div class="brand-name">
    $productHref[$key]["product-name"] = $pq->find(".product-name h1")->text();

    // PhpQuery позволяет перечислять классы нескольких, вложенных друг в друга, элементов.
    // Только не забывайте следить за порядком!
    // Тут мы получаем цену товара.
    $productHref[$key]["product-price"] = $pq->find(".price-info .price-box .regular-price .price")->text();

    // Получаем описание товара
    $productHref[$key]["product-description"] = $pq->find(".description .product-description")->text();

    // Так же есть возоможность шагать по элементам.
    // Деется это с помощью метода next();
    // В данном случае мы получим только числовой идентификатор без лишних строк.
    $productHref[$key]["product-id"] = $pq->find(".description .sku span")->next()->text();
    
}


а можно было вот так:
$html = file_get_contents("https://какой-то_сайт.com/");

$crawler = (new Crawler($html));
$productHref = $crawler->filter('.product-essential')->each($node) {
    return [
        'brand-href'          => $node->filter('.brand-link')->first()->attr('href'),
        'brand-name'          => $node->filter('.brand-name')->first()->text(),
        'product-name'        => $node->filter('.product-name h1')->first()->text(),
        'product-price'       => $node->filter('.price-info .price-box .regular-price .price')->text(),
        'product-description' => $node->filter('.description .product-description')->text(),
        'product-id'          => $node->filter('.description .sku span')->eq(1)->text(),
    ];    
});


Сильно сложно?
Спасибо, надо будет попробовать прикрутить ssi, пощупать.
С lua не очень нравится ресурсоемкость, — по ощущениям раза в два больше, чем голые proxy_pass жрёт, поэтому хотелось бы использовать её только как header_filter и т.п.
Большое спасибо!
Очень люблю почитать вот такие истории, особенно когда в них фигурирует php:)

Насчет ssi думал когда нужно было склеивать несколько файлов и отдавать как один, но как-то дальше думать это не пошло и пока все это дело на lua.
Вообще реально им собирать несколько удаленных файлов в один?
То есть у меня есть location с proxy_pass, который отдает файл откуда-то.
но файл может быть разбит на насколько (ну, например, зип-архив просто разбитый на куски по 200мб, не многотомник) и пользователю нужно, соответственно, отдать нормальный файл, а не 2-3куска. я могу отдать из php такой ssi, чтоб nginx последовательно подсунул пользователю несколько кусков как один файл?

На самом деле я, конечно же, утрирую — мы же не на голом PHP хеш считаем, а больше там числодробительного ничего и нет. Практически только IO-операции.
Возможно, с появлением jit в релизных версиях, подобные темы вообще станут чем-то обыденным для нашего сообщества.
У популярных облачных хранилищ скорей всего есть предрасчитанный crc32, что немного им упрощает дело.
Я постараюсь в следующей статье показать вариант, когда мы даже не знаем размер упаковываемых файлов (например, у нас список URL, а мы хотим собрать zip-архив с содержимым), но можем это все упаковывать на лету и отдавать пользователю одновременно с прогрессом скачивания файла нами.
Но и про ваш вариант, думаю, расскажу :)
А можно даже этот бекап прям сразу на лету и заливать куда-нибудь в облако, не сохраняя у себя вообще никаких временных данных.
PHP позволяет считать хеши инрементально, так что это очень даже возможно и, вроде, не сложно.
Я думаю, что следующая статья как раз про это и будет, постараюсь только набросать хоть как-нибудь интересный proof of concept, чтоб это можно было запустить и пощупать результат.
Ну, я с zip тоже не за 5 минут разобрался)
Главное время и упорство, а там все получится.
На всякий случай не буду обещать что-нибудь, но в планах маленький цикл статей о zip, php и nginx, что с этим всем можно делать. И тут zip больше как контейнер (не рассматривал tar, потому что он не так широко распространен среди обычных пользователей, хотя когда-то, давным-давно, по мотивам одной статьи писал tar-упаковщик, тоже на php). Но если будут силы, я очень постараюсь не обойти тему сжатия стороной.
PHP ничего не отслеживает при изменении файлов, просто если стоит opcache.validate_timestamps, то при попытке использовать файл, php обратиться к диску и сверит дату изменения файла. То есть это дополнительное время на медленную io-операцию.
Preload фактически расширяет возможность не сбрасывать кеш опкеша, позволяя это для конкретных файлов (как часто у вас на продакшн меняется содержимое папки vendor? да даже на дев), в то время как до этого opcache.validate_timestamps кешировал намертво всё.

И суть умирания после запроса не только в этом, а больше в изоляции запросов друг от друга.

Information

Rating
Does not participate
Location
Украина
Registered
Activity