【问题标题】:Odd recursion error in parsing MIME message解析 MIME 消息时出现奇怪的递归错误
【发布时间】:2012-10-13 07:00:49
【问题描述】:

好的,我必须管理我不是递归大师。这可能是一个新手问题。

我要做的是计算节号。正如您所看到的,随着您的深入,部分编号会以可预测的方式发生变化

multipart/mixed
 -- (part 0, sec. "1") multipart/related
    -- (part 0, sec. "1.1") multipart/alternative
       -- (part 0, sec. "1.1.1") text/plain
       -- (part 1, sec. "1.1.2") text/html
    -- (part 1, sec. "1.2") image/gif
 -- (part 1, sec. "2") image/png

也就是说,节号只是零件号(加1)后跟一个点,然后是零件号(加1),次数取决于嵌套级别。

一个简单的$struct 传递给parse() 函数如下:

object(stdClass)
   public 'type' => int // if 1 it's multipart
   public 'parts' => array // Inner parts

虽然我的功能是这样的:

public function parse($struct, $depth = '')
{
   if(!isset($struct->parts)) return; // Base case of recursion: no parts inside

   // $struct->parts is array: index starting from 0.
   for($i = 0, $j = count($struct->parts); $i < $j; $i++)
   {
      $part = $struct->parts[$i]; // Current part
      $ptno = $i + 1; // This is the part number, will be used to build $secno

      // Multipart? Go further in recursion passing the new level of nesting
      if($part->type == 1) $this->parse($part, $depth .= "$partno" . ".");

      // Compute the section number with the given $depth (if any)
      // ACTUALLY NOT WORKING
      $secno = !empty($depth) ? "$depth$ptno" : "$ptno";

      // Where am i?
      echo self::$TYPES[$part->type] . '/' . $part->subtype . ": $secno<br/>";
   }
}

输出(错误):

text/PLAIN: 1.1.1
text/HTML: 1.1.2
multipart/ALTERNATIVE: 1.1.1
image/GIF: 1.1.2
multipart/RELATED: 1.1
image/PNG: 1.2

应该是这样的

text/PLAIN: 1.1.1
text/HTML: 1.1.2
multipart/ALTERNATIVE: 1.1
image/GIF: 1.2
multipart/RELATED: 1
image/PNG: 2

编辑:复制和粘贴测试数据:

$test = (object) array(
    'type' => 1, // multipart
    'subtype' => 'MIXED',
    'parts' => array(
        (object) array(
            'type'    => 1, // multipart
            'subtype' => 'RELATED',
            'parts'   => array(
                (object) array(
                    'type'    => 1, // multipart
                    'subtype' => 'ALTERNATIVE',
                    'parts'   => array(
                        (object) array('type' => 0, 'subtype' => 'PLAIN'),
                        (object) array('type' => 0, 'subtype' => 'HTML'),
                    )
                ),
                (object) array(
                    'type'    => 5, // image
                    'subtype' => 'GIF'
                )
            )
        ),
        (object) array(
            'type'    => 5, // image
            'subtype' => 'PNG'
        )
    )
);

【问题讨论】:

  • @ajreal 给我五分钟,我将编辑第一篇文章。谢谢。

标签: php email recursion mime-types


【解决方案1】:

问题是你是.= 附加$partno 而你应该只是. 附加在这里:

$this->parse($part, $depth .= "$partno" . ".");

因此,在您的代码上下文中修复它,您会得到:

public function parse($struct, $depth = '')
{
   if(!isset($struct->parts)) return; // Base case of recursion: no parts inside

   // $struct->parts is array: index starting from 0.
   for($i = 0, $j = count($struct->parts); $i < $j; $i++)
   {
      $part = $struct->parts[$i]; // Current part
      $ptno = $i + 1; // This is the part number, will be used to build $secno

      // Multipart? Go further in recursion passing the new level of nesting
      if($part->type == 1) $this->parse($part, $depth . "$partno" . ".");

      // Compute the section number with the given $depth (if any)
      $secno = !empty($depth) ? "$depth$ptno" : "$ptno";

      // Where am i?
      echo self::$TYPES[$part->type] . '/' . $part->subtype . ": $secno<br/>";
   }
}

您可以像这样重组您的代码,以避免更多的代码重复:

public function parse($struct, $depth = '')
{
   if(!isset($struct->parts)) return; // Base case of recursion: no parts inside

   // $struct->parts is array: index starting from 0.
   for($i = 0, $j = count($struct->parts); $i < $j; $i++)
   {
      $part = $struct->parts[$i]; // Current part
      $ptno = $i + 1; // This is the part number, will be used to build $secno

      // Compute the section number with the given $depth (if any)
      $secno = $depth . $ptno

      // Multipart? Go further in recursion passing the new level of nesting
      if($part->type == 1) $this->parse($part, $secno . '.');

      // Where am i?
      echo self::$TYPES[$part->type] . '/' . $part->subtype . ": $secno<br/>";
   }
}

【讨论】:

  • 你真的让我很开心,你不知道有多少 :) 非常感谢! +1 并接受回答!
【解决方案2】:

你的递归调用

$this->parse($part, $depth .= "$partno" . ".");

应该阅读

$this->parse($part, $depth . "$partno" . ".");

相反。否则,您将更改变量 $depth

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-30
    • 2020-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-28
    • 2013-07-11
    • 2010-11-05
    相关资源
    最近更新 更多