【问题标题】:PHP/Ruby Zlib EquivalencePHP/Ruby Zlib 等价
【发布时间】:2012-02-07 02:04:35
【问题描述】:

我想知道与这段代码等效的 PHP 是什么:

require "zlib"
foo = Zlib::Deflate.new()
bar = "bar"
puts foo.deflate(bar, Zlib::SYNC_FLUSH).unpack('H*')
puts foo.deflate(bar, Zlib::SYNC_FLUSH).unpack('H*')
puts foo.deflate(bar, Zlib::SYNC_FLUSH).unpack('H*')
foo.close()

输出:

789c4a4a2c02000000ffff
4a4a2c02000000ffff
022200000000ffff

我尝试过使用gzdeflate()gzcompress()compress.zlib:// 流等,但找不到正确的等价物。

编辑:

应该注意,这个问题的用例是用于 TCP 连接的持久 Zlib 流,不是用于简单的网页压缩。换句话说,对 deflate 的连续调用应该使用 same Zlib 流。 PHP 当前允许这样做,但没有提供手动刷新的方法(例如SYNC_FLUSH),并且将等待刷新直到流关闭。这对于我的用例来说是不可接受的,因为我需要能够在任何给定点刷新以将压缩数据发送到该点到远程客户端。

编辑#2:

另请参阅this previous question,以更深入地分析为什么 PHP 不允许 SYNC_FLUSH。我正在寻找一个 hack 或解决方法,直到 PHP 最终被修补以解决它(不幸的是,如果它 修补,它可能会在 5.4 分支中,我不会能够使用很长时间,因此解决方法变得更加重要)。

【问题讨论】:

    标签: php ruby zlib


    【解决方案1】:

    嗯,有一个 PECL http 扩展,特别适合您的需求。 :)

    <?php
    $stream = new HttpDeflateStream(HttpDeflateStream::FLUSH_SYNC);
    echo bin2hex($stream->update('bar')) . PHP_EOL;
    echo bin2hex($stream->update('bar')) . PHP_EOL;
    echo bin2hex($stream->update('bar')) . PHP_EOL;
    
    $ php test.php
    789c4a4a2c02000000ffff
    4a4a2c02000000ffff
    022200000000ffff
    

    希望对您有所帮助。手动:http://php.net/manual/en/class.httpdeflatestream.php

    【讨论】:

    • 这正是我想要的!谢谢!
    【解决方案2】:

    这是我得到的:

    $ php -a
    Interactive shell
    
    php > echo bin2hex(gzcompress('bar'));
    789c4b4a2c0200025d0136
    php > echo bin2hex(gzdeflate('bar'));
    4b4a2c0200
    

    我发现了一篇关于这个主题的有趣文章:http://www.agileweboperations.com/how-inflate-and-deflate-data-ruby-and-php


    我玩多了,就到了这个:

    include 'zlib.php';
    $foo = new Zlib_Deflate();
    $bar = 'bar';
    echo bin2hex($foo->deflate($bar)) . "\n";
    echo bin2hex($foo->deflate($bar)) . "\n";
    echo bin2hex($foo->deflate($bar)) . "\n";
    $foo->close();
    

    输出:

    789c4b4a2c02000000ffff
    4a4a2c02000000ffff
    0223000000ffff
    

    下面是“zlib.php”的内容:

    class Zlib_Deflate
    {
        private $stream = '';
        private $deflated = '';
        public function deflate($string)
        {
            $new = empty($this->stream);
            $this->stream .= $string;
            $deflated = gzdeflate($this->stream);
            $deflated_diff = $this->diff($this->deflated, $deflated);
            $this->deflated = $deflated;
            return ($new ? pack('H*', '789c') : '') . $deflated_diff . pack('H*', '0000ffff');
        }
        private function diff($str1, $str2)
        {
            $result = '';
            $max = strlen($str2);
            for($i = 0; $i < $max; $i++)
                if ($str1[$i] != $str2[$i])
                    break;
            return substr($str2, $i);
        }
        public function close()
        {
            $this->stream = '';
        }
    }
    

    当然,我们不能认真对待这件事。这是幼儿园代码。

    无论如何,它带来了一些亮点,并提供了一些关于这个问题的线索......

    想要的函数确实是gzdeflate。在上面链接的文章中,您将了解如何轻松使 Ruby deflate 像 PHP 一样工作。然而,相反的(让 PHP deflate 像 RubY 一样工作)并不简单。

    【讨论】:

    • 感谢您的深入回答,但是,相反的场景(使 PHP 像 Ruby 一样工作)正是我正在寻找的。​​span>
    • 我查看了 Ruby 的 Zlib 源代码(我建议你这样做),在我看来,它非常复杂/高级/“严肃的东西”——不是几个小时就能翻译的东西。 ..
    猜你喜欢
    • 1970-01-01
    • 2011-07-17
    • 2011-03-22
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 2019-03-11
    • 1970-01-01
    • 2019-08-15
    相关资源
    最近更新 更多