Making a self-extracting archive or sections in PHP files

    Only one thing motivated me to write this code - dumb FTP of some hosters.
    No, the files are uploaded at maximum speed, but 30 seconds elapse between the end of downloading one file and the start of the next one.
    Since I ’m crap and put jomls in shock quantities, downloading 5000+ files leads to reading the hub and google reader to the holes, which, however, is also unhealthy.
    In order to correct this annoying omission, a small patella script is written.



    As you know, a script is such a thing that it can be launched not only on the server, but also from the console, which means that it is necessary to provide for the performance of both options. Isset ($ argv) is
    used to determine the console
    Actually, the packaging and unpacking code itself is not interesting.
    And here what I would like to pay attention to% username% so how exactly the packer is organized.
    To do this, I’m talking about one function and one constant that not only schoolchildren and Indians do not know about.

    This is the __compiler_halt function and the __COMPILER_HALT_OFFSET__ constant , both introduced in PHP starting with 5.1
    When parsing a file if php runs into __compiler_halt (); then it completes the parsing and sets in __COMPILER_HALT_OFFSET__ the number of bytes following the semicolon after the function name.
    It is important to understand that there are none?> it is no longer required after this construction.
    What does this give us?
    And it gives us the opportunity to store all sorts of rubbisharbitrary data in our php code.
    And this data is read very easily: file_get_contents (__ FILE __, null, null, __ COMPILER_HALT_OFFSET__);
    If this is to use the file turns out to be divided into 2 sections - the code section and a data

    packer contains sections packing code code, and the code section data unpacking
    Unpacking the same in the code section contains a loved one, and in the data section - zip archive c data

    is not bothering any further I use a rant to quote the code: well, for today it’s all I wanted to say, unless in violation of traditions I’ll ask you to kick the jambs in the first post on the hub, otherwise it will be too late :)


    $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(); $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 <<

    Упакованный архив $file


    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 << Extract me with
        php $file extract
    Unpack me with
        php $file unpack

    HEREDOC;
        }
        else
        {
            echo 'Распаковать архив
    Извлечь архив';
        }
    }
    if(!isset($argv)) echo '';
    __halt_compiler();




    Also popular now: