Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

How to passthru 7za output using PHP

Louis
2010-08-27
2013-05-28
  • Louis
    Louis
    2010-08-27

    For the past 3 days now I have been searching the web for a solution which would allow me to use 7-zip to compress some folder and output the compressed data as it is being generated to the browser in PHP. I am running PHP 5.3.3 and p7zip 9.04 x86_64 on Fedora 13. I have tried the following different code segments and none work…

    First try:

    passthru("/usr/bin/7za a dummy -tzip -so \"".$filepath."\"");
    

    This code does nothing, no output to browser…

    Second try:

    system("/usr/bin/7za a dummy -tzip -so \"".$filepath."\"");
    

    This code also does nothing…

    Third try:

            $cmd = "/usr/bin/7za a dummy -tzip -so \"".$filepath."\"";
        header("Content-type: application/zip");
        header("Content-Transfer-Encoding: Binary");
        header("Content-disposition: attachment; filename=\"".$first[sizeof($first)-2].'.zip'."\"");
        $buf_siz = 1024;        # max buffer size
        $fd_write = 0;        # stdin
        $fd_read = 1;        # stdout
        $fd_err = 2;        # stderr
        $descriptorspec = array(
            0 => array("pipe", "r"),
            1 => array("pipe", "w"),
            2 => array("pipe", "w")
        );
        $ptr = proc_open($cmd, $descriptorspec, $pipes, NULL, $_ENV);
        if (!is_resource($ptr)){
            return false;
        }
            while (($buffer = fgets($pipes[$fd_read], $buf_siz)) != NULL || ($errbuf = fgets($pipes[$fd_err], $buf_siz)) != NULL) {
                if (!isset($flag)) {
                    $pstatus = proc_get_status($ptr);
                    $first_exitcode = $pstatus["exitcode"];
                    $flag = true;
                }
                if (strlen($buffer)){
                    echo $buffer;
                }
                if (strlen($errbuf)){
                    echo $errbuf;
                }
            }
        foreach ($pipes as $pipe){
            fflush($pipe);
            fclose($pipe);
        }
        /* Get the expected *exit* code to return the value */
        $pstatus = proc_get_status($ptr);
        if (!strlen($pstatus["exitcode"]) || $pstatus["running"]) {
            if ($pstatus["running"])
                proc_terminate($ptr);
            $ret = proc_close($ptr);
        } else {
            if ((($first_exitcode + 256) % 256) == 255 && (($pstatus["exitcode"] + 256) % 256) != 255)
                $ret = $pstatus["exitcode"];
            elseif (!strlen($first_exitcode))
                $ret = $pstatus["exitcode"];
            elseif ((($first_exitcode + 256) % 256) != 255)
                $ret = $first_exitcode;
            else
                $ret = 0;
            proc_close($ptr);
        }
        $ret = ($ret + 256) % 256;
    

    This code outputs the following line to the browser from stderr:
    7-Zip (A) 9.04 beta Copyright (C) 1999-2009 Igor Pavlov 2009-05-30 p7zip Version 9.04 (locale=C,Utf16=off,HugeFiles=on,8 CPUs) Scanning Creating archive stdout System error: E_NOINTERFACE

    If anyone knows how I can get this to work I would be very happy to hear the solution. I am familiar with many languages so if the solution is complicated that is okay, I would love to hear it anyways. Is this even possible with p7zip at the moment? I would think it should be…

     
  • Louis
    Louis
    2011-01-06

    It has been 5 months and I am very surprised that no one has been able to provide any information about this issue. This seems like a very useful thing. If anyone has any information about how to do this please let me know.