2015-05-27 141 views
-2

我写了一个函数,它将包含PDF字段数据的字符串传递到preg_match_all()作为主题。然而,无论我做什么,我都无法得到预期的输出,因为我在这里得到http://www.phpliveregex.com/p/bjN。在我的开发环境,我得到这个:PHP pdftk ASCII编码问题

阵列(1){[0] =>阵列(0){}}

我已经能够得到这个唯一的办法工作是通过调用我的字符串输入的var_dump(),将其分配给函数中的一个变量,并用反斜杠转义双引号。然而,这个解决方案不起作用,因为我想动态地传递不同的字符串。

我已经尝试过的函数包括preg_replace(),preg_quote(),addslashes(),addcslashes()和htmlentities()来转义或编码可能导致问题的任何字符。到目前为止没有任何工作。

下面引用是我在输入中调用var_dump()时得到的输出。正如我上面所说的,将它分配给一个变量并传递给preg_match_all()对我来说是有效的。所以这个问题似乎正在下降到这样的程度:什么可能会阻止我的输入字符串与preg_match_all()正常工作,这不是我在调用var_dump()时得到的字符串的问题?

串(3277)“---的FieldType:文本字段名: FC-INT01-generateAppearances FieldFlags:5 FieldJustification:左 ---的FieldType:文本字段名:蛋糕的大小,形状,和Pricing_edit; _aKGrUPU76IVzjjqnxACWRA FieldNameAlt :请说明 定制的蛋糕大小和特殊要求。FieldFlags:0 FieldFusion:Left --- FieldType:Text FieldName:Todays Date FieldNameAlt:Today's date FieldFlags:0 FieldJustification:Left --- FieldType:Button FieldName:Type FieldFlags :49152 栏位理由:Left FieldStateOption:用于交付 FieldStateOption:用于提货F ieldStateOption:Off --- FieldType: FieldName:Name FieldNameAlt:Name FieldFlags:0 FieldJustification:Left --- FieldType:Text FieldName:Event Date of Event FieldNameAlt:事件日期FieldFlags:0 FieldJustification:Left --- 的FieldType:文本字段名:在 事件FieldFlags的时间:事件FieldNameAlt的时间0 FieldJustification:左---的FieldType:文本 字段名:事件FieldNameAlt类型:事件FieldFlags类型:0 FieldJustification:左---的FieldType :文本字段名称:事件位置 (如果需要传递)FieldNameAlt:事件位置(如果要求传递 )FieldFlags:0 FieldJustification:Left --- FieldType: Text FieldName:Pick Up Time FieldName Alt:接机时间FieldFlags:0 FieldJustification:Left --- FieldType:Text FieldName:Number of Guests FieldNameAlt:客人人数FieldFlags:0 FieldJustification:Left --- FieldType:Text FieldName:Phone Number FieldNameAlt:Phone FieldFlags:0 FieldJustification:Left --- FieldType:Button FieldName:蛋糕大小,形状和价格FieldFlags: 49152 FieldJustification:Left FieldStateOption:Custom FieldStateOption:Off FieldStateOption:Rectangle 1/2 Sheet($ 60.00) 送达到12 FieldStateOption:矩形1/3工作表($ 40.00)服务 最多8 FieldStateOption:矩形1/4工作表($ 30.00)服务多达6 FieldStateOption:矩形工作表($ 100.00)服务最多24 FieldStateOption:第6轮“($ 40。00)服务多达8 FieldStateOption:第9轮“(50.00美元)最多可服务16个 FieldStateOption:Square 1/6 Sheet($ 20.00)最多可提供4个 FieldStateOption:Square 2/3 Sheet($ 50.00) - 的FieldType:按钮字段名:蛋糕口味FieldFlags:49152 FieldJustification:左FieldStateOption:胡萝卜FieldStateOption: 巧克力FieldStateOption:柠檬FieldStateOption:关 FieldStateOption:红色天鹅绒FieldStateOption:香草---的FieldType: 键字段名:蛋糕馅料FieldFlags :49152 FieldJustification: Left FieldStateOption:Buttercream FieldStateOption:奶酪 FieldStateOption:黑巧克力FieldStateOption:柠檬凝乳 Fi eldStateOption:关FieldStateOption:草莓慕斯--- 的FieldType:按钮字段名:蛋糕蒙砂FieldFlags:49152 FieldJustification:左FieldStateOption:巧克力奶油 FieldStateOption:奶油奶酪FieldStateOption:关FieldStateOption: 草莓奶油FieldStateOption:香草奶油 FieldStateOption:鞭打奶油---字段类型:文本字段名称:蛋糕 写字的题字和颜色FieldNameAlt:蛋糕题字和 写字的颜色FieldFlags:4096 FieldJustification:Left --- FieldType:Text FieldName:浇头和特殊装饰 FieldNameAlt:浇头和特殊装饰品FieldFlags:4096 FieldJustification:Left“

如果将此字符串分配给临时变量并转义引号,则preg_match_all()将按预期工作。当我使用分配的字符串在这个变量上调用var_dump()时,长度为3268个字符,而我的直接输入为3277(上面)。所以也许有一些奇怪的事情与输入字符串。

任何帮助,将不胜感激!

这里是我已经修改,以加强对这里的可读性我的类文件:

class Pdf_form { 

    public function get_pdf_fields($pdf) { 
     $cmd = "pdftk $pdf dump_data_fields output -"; 

     $descriptorspec = array(
      1 => array("pipe", "w") 
     ); 

     $process = proc_open($cmd, $descriptorspec, $pipes); 

     if(!is_resource($process)) { 
      return FALSE; 
     } 

     $dump_data = stream_get_contents($pipes[1]); 
     fclose($pipes[1]); 

     $status = proc_close($process); 

     return $this->parse_fields($dump_data); 
    } 

    private function parse_fields($dump_data) { 
     preg_match_all('/FieldType: .+?(?= ---|$)/', $dump_data, $field_data); 

     return $field_data; 
    } 
} 
+0

_“由于存在$和”(双引号)字符,因此无法将其作为输入传递到preg_match_all“_你为什么会这么想?这显然是主题而不是模式,并且这些字符不会呈现一个问题。 – AbraCadaver

+0

你说得对,我引用的字符串是主题。我不认为会有任何问题,我自己直到preg_match_all()返回此“阵列(1){[0] =>阵列(0){} }“。只有在我逃过$和”用反斜线preg_match_all()返回我的预期。 - 编辑:对于不需要转义的美元符号,您是正确的,因为我刚刚测试了这一点,但双引号在逃脱之前仍然存在问题。 –

+0

你可以发布你如何在'preg_match_all'或'preg_replace'中运行这个字符串吗? – chris85

回答

0

您可以使用Newdoc语法我想。

文档中的示例。

echo <<<'EOT' 
My name is "$name". I am printing some $foo->foo. 
Now, I am printing some {$foo->bar[1]}. 
This should not print a capital 'A': \x41 
EOT; 

https://php.net/language.types.string#language.types.string.syntax.nowdoc11

编辑 如果你只是想取代你可以使用str_replace函数所有双qoutes。

$a = str_replace('"', '\"', $a);

+0

我看不出这将如何工作,除非有一个办法,我以某种方式将我的动态输入字符串转换成nowdoc格式。 –

+0

我错过了这个问题。但是,这应该与\更换所有双qoutes“'$字符串= str_replace函数(“””,“\”“,$字符串);' – Karl

+0

的问题之前,应进行首次发现。‘修复’没有理由双引号 – chris85

-1

如果您使用的mysqli连接 传中,PHP函数

mysqli_real_escape_string(); 

的字符串,如果用mysql然后用

mysql_real_escape_string(); 
+0

什么?没有数据库在这里谈论。 – chris85

+0

即使您不想将记录保存在数据库中,也可以使用此功能。我的意思是无论你想插入数据库还是存储变量,它都会返回相同的结果。 –

+0

没有第一个它会发出警告。 '警告:mysql_real_escape_string():[2002]没有这样的文件或目录(试图通过unix连接:///var/mysql/mysql.sock)'''警告:mysql_real_escape_string():到服务器的链接不能建立在',等等。如果目标只是为了逃避报价为什么不http://php.net/addslashes?但即便如此,这也不是问题。 – chris85

0

原来一些,也许甚至所有在我的输入中似乎都是空格的字符实际上都被编码为ASCII换行符(ASCII十进制代码10)。因此,在调用pdftk的dump_data_fields操作和通过stream_get_contents()将数据管道传输到我的php脚本之间,以这种方式编码数据。

我的解决方案是调用我的输入上的preg_replace()以用空格替换所有换行符。这是它看起来像:

$dump_data = preg_replace('/\n/', ' ', $dump_data); 

preg_match_all('/FieldType:.+?(?=.---|$)/', $dump_data, $field_data); 

希望这可以帮助别人!