Побудила писать этот код меня только одна вещь — тупые FTP некоторых хостеров.
Нет, файлы заливаются с максимальной скоростью, но вот между окончанием загрузки одного файла и началом загрузки следующего проходит секунд 30.
Так как я сейчас страдаю хренью верстаю и ставлю джомлы в ударных количествах, загрузка 5000+ файлов приводит к зачитыванию хабры и гуглридера до дыр, что однако тоже вредно для здоровья.
С целью исправить сиё досадное упущение и пишется небольшой наколеночный скриптик.
Скриптик как известно штука такая что его не только на сервере, но и из консоли запускать можно, а значит надо предусмотреть работоспособность обоих вариантов.
Для определения консоли используется isset($argv)
Собственно сам код упаковки и распаковки не интересен.
А вот на что я бы хотел обратить внимание %username% так на то как именно организован упаковщик.
Для этого рассказываю про одну функцию и одну константу о которой не знают не только школьники и индусы.
Это функция __compiler_halt и константа __COMPILER_HALT_OFFSET__, обе введены в PHP начиная с 5.1
При парсинге файла если php натыкается на __compiler_halt(); то он завершает парсинг и выставляет в __COMPILER_HALT_OFFSET__ номер байта следующего за точкой с запятой после имени функции
Важно понимать что никаких ?> уже не требуется после этой конструкции
Что же это нам даёт?
А даёт это нам возможность хранитьвсякую дрянь произвольные данные в нашем php коде
Причём считываются эти данные очень легко: file_get_contents(__FILE__,null,null,__COMPILER_HALT_OFFSET__);
Если это использовать файл получается разбитым на 2 секции — секцию кода и секцию данных
Упаковщик содержит в секции кода код упаковки, а в секции данных код распаковки
Распаковщик же в секции кода содержит себя любимого, а в секции данных — zip архив c данными
Не надоедая дальнейшими разглагольствованиями привожу код:
ну, на сегодя это всё что я хотел сказать, разве что нарушая традиции попрошу попинать ногами за косяки в первом посте на хабре, иначе будет поздно :)
Нет, файлы заливаются с максимальной скоростью, но вот между окончанием загрузки одного файла и началом загрузки следующего проходит секунд 30.
Так как я сейчас
С целью исправить сиё досадное упущение и пишется небольшой наколеночный скриптик.
Скриптик как известно штука такая что его не только на сервере, но и из консоли запускать можно, а значит надо предусмотреть работоспособность обоих вариантов.
Для определения консоли используется isset($argv)
Собственно сам код упаковки и распаковки не интересен.
А вот на что я бы хотел обратить внимание %username% так на то как именно организован упаковщик.
Для этого рассказываю про одну функцию и одну константу о которой не знают не только школьники и индусы.
Это функция __compiler_halt и константа __COMPILER_HALT_OFFSET__, обе введены в PHP начиная с 5.1
При парсинге файла если php натыкается на __compiler_halt(); то он завершает парсинг и выставляет в __COMPILER_HALT_OFFSET__ номер байта следующего за точкой с запятой после имени функции
Важно понимать что никаких ?> уже не требуется после этой конструкции
Что же это нам даёт?
А даёт это нам возможность хранить
Причём считываются эти данные очень легко: file_get_contents(__FILE__,null,null,__COMPILER_HALT_OFFSET__);
Если это использовать файл получается разбитым на 2 секции — секцию кода и секцию данных
Упаковщик содержит в секции кода код упаковки, а в секции данных код распаковки
Распаковщик же в секции кода содержит себя любимого, а в секции данных — zip архив c данными
Не надоедая дальнейшими разглагольствованиями привожу код:
<?php
$packname = getcwd().'/'.basename(__FILE__,'.php').'.packed.php';
$zip = new ZipArchive();
$zip->open($packname, ZIPARCHIVE::CREATE|ZIPARCHIVE::OVERWRITE);
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('./'));
$packer = realpath(__FILE__);
foreach($iterator as $key=>$value)
{
$file = realpath($key);
if($file!=$packer)
$zip->addFile($file,$key);
}
$zip->close();
$data = file_get_contents(__FILE__,null,null,__COMPILER_HALT_OFFSET__);
$zipped = @file_get_contents($packname);
if($zipped=='') die();
file_put_contents($packname,$data.$zipped);
__halt_compiler();<?php
$mode = '';
if(isset($argv[1]))
{
$mode = $argv[1];
}
if(isset($_REQUEST['mode']))
{
$mode = $_REQUEST['mode'];
}
function extract_archive()
{
file_put_contents(getcwd().'/'.basename(__FILE__).'.zip',file_get_contents(__FILE__,null,null,__COMPILER_HALT_OFFSET__));
}
$file = basename(__FILE__);
if(!isset($argv))
echo <<<HEREDOC
<html>
<head>
<title>Упакованный архив $file</title>
</head>
<body style="font-size:24px;">
HEREDOC;
switch($mode)
{
case 'extract':
extract_archive();
echo "Извлечён\n";
break;
case 'unpack':
extract_archive();
$zip = new ZipArchive;
$zip->open(getcwd().'/'.basename(__FILE__).'.zip');
$zip->extractTo('./');
$zip->close();
unlink(getcwd().'/'.basename(__FILE__).'.zip');
unlink(__FILE__);
echo "Распакован\n";
break;
default:
if(isset($argv))
{
echo <<<HEREDOC
Extract me with
php $file extract
Unpack me with
php $file unpack
HEREDOC;
}
else
{
echo '<a href="?mode=unpack">Распаковать архив</a><br><a href="?mode=extract">Извлечь архив</a>';
}
}
if(!isset($argv)) echo '</body></html>';
__halt_compiler();
ну, на сегодя это всё что я хотел сказать, разве что нарушая традиции попрошу попинать ногами за косяки в первом посте на хабре, иначе будет поздно :)