ошибка смещения в PHP при преобразовании данных в текстовый документ - PullRequest
0 голосов
/ 26 июня 2011

Получение неопределенного смещения: 1 ошибка при попытке следующего кода, который выводит некоторые данные в документ word ...

Использование CodeIgniter в контроллере у меня:

$htmltodoc= new HTML_TO_DOC();
$htmltodoc->createDoc("<h1>Testing data </h1>", "testfile.doc");

В каталоге помощника я использую следующие функции в классе HTML_TO_DOC ниже ...

 class HTML_TO_DOC
{
    var $docFile="";
    var $title="";
    var $htmlHead="";
    var $htmlBody="";


    /**
     * Constructor
     *
     * @return void
     */
    function HTML_TO_DOC()
    {
        $this->title="Untitled Document";
        $this->htmlHead="";
        $this->htmlBody="";
    }

    /**
     * Set the document file name
     *
     * @param String $docfile 
     */

    function setDocFileName($docfile)
    {
        $this->docFile=$docfile;
        if(!preg_match("/\.doc$/i",$this->docFile))
            $this->docFile.=".doc";
        return;        
    }

    function setTitle($title)
    {
        $this->title=$title;
    }

    /**
     * Return header of MS Doc
     *
     * @return String
     */
    function getHeader()
    {
        $return  = <<<EOH
         <html xmlns:v="urn:schemas-microsoft-com:vml"
        xmlns:o="urn:schemas-microsoft-com:office:office"
        xmlns:w="urn:schemas-microsoft-com:office:word"
        xmlns="http://www.w3.org/TR/REC-html40">

        <head>
        <meta http-equiv=Content-Type content="text/html; charset=utf-8">
        <meta name=ProgId content=Word.Document>
        <meta name=Generator content="Microsoft Word 9">
        <meta name=Originator content="Microsoft Word 9">
        <!--[if !mso]>
        <style>
        v\:* {behavior:url(#default#VML);}
        o\:* {behavior:url(#default#VML);}
        w\:* {behavior:url(#default#VML);}
        .shape {behavior:url(#default#VML);}
        </style>
        <![endif]-->
        <title>$this->title</title>
        <!--[if gte mso 9]><xml>
         <w:WordDocument>
          <w:View>Print</w:View>
          <w:DoNotHyphenateCaps/>
          <w:PunctuationKerning/>
          <w:DrawingGridHorizontalSpacing>9.35 pt</w:DrawingGridHorizontalSpacing>
          <w:DrawingGridVerticalSpacing>9.35 pt</w:DrawingGridVerticalSpacing>
         </w:WordDocument>
        </xml><![endif]-->
        <style>
        <!--
         /* Font Definitions */
        @font-face
            {font-family:Verdana;
            panose-1:2 11 6 4 3 5 4 4 2 4;
            mso-font-charset:0;
            mso-generic-font-family:swiss;
            mso-font-pitch:variable;
            mso-font-signature:536871559 0 0 0 415 0;}
         /* Style Definitions */
        p.MsoNormal, li.MsoNormal, div.MsoNormal
            {mso-style-parent:"";
            margin:0in;
            margin-bottom:.0001pt;
            mso-pagination:widow-orphan;
            font-size:7.5pt;
                mso-bidi-font-size:8.0pt;
            font-family:"Verdana";
            mso-fareast-font-family:"Verdana";}
        p.small
            {mso-style-parent:"";
            margin:0in;
            margin-bottom:.0001pt;
            mso-pagination:widow-orphan;
            font-size:1.0pt;
                mso-bidi-font-size:1.0pt;
            font-family:"Verdana";
            mso-fareast-font-family:"Verdana";}
        @page Section1
            {size:8.5in 11.0in;
            margin:1.0in 1.25in 1.0in 1.25in;
            mso-header-margin:.5in;
            mso-footer-margin:.5in;
            mso-paper-source:0;}
        div.Section1
            {page:Section1;}
        -->
        </style>
        <!--[if gte mso 9]><xml>
         <o:shapedefaults v:ext="edit" spidmax="1032">
          <o:colormenu v:ext="edit" strokecolor="none"/>
         </o:shapedefaults></xml><![endif]--><!--[if gte mso 9]><xml>
         <o:shapelayout v:ext="edit">
          <o:idmap v:ext="edit" data="1"/>
         </o:shapelayout></xml><![endif]-->
         $this->htmlHead
        </head>
        <body>
        EOH;
    return $return;
    }

    /**
     * Return Document footer
     *
     * @return String
     */
    function getFotter()
    {
        return "</body></html>";
    }

    /**
     * Create The MS Word Document from given HTML
     *
     * @param String $html :: URL Name like http://www.example.com
     * @param String $file :: Document File Name
     * @param Boolean $download :: Wheather to download the file or save the file
     * @return boolean 
     */

    function createDocFromURL($url,$file,$download=false)
    {
        if(!preg_match("/^http:/",$url))
            $url="http://".$url;
        $html=@file_get_contents($url);
        return $this->createDoc($html,$file,$download);    
    }

    /**
     * Create The MS Word Document from given HTML
     *
     * @param String $html :: HTML Content or HTML File Name like path/to/html/file.html
     * @param String $file :: Document File Name
     * @param Boolean $download :: Wheather to download the file or save the file
     * @return boolean 
     */

    function createDoc($html,$file,$download=false)
    {
        if(is_file($html))
            $html=@file_get_contents($html);

        $this->_parseHtml($html);
        $this->setDocFileName($file);
        $doc=$this->getHeader();
        $doc.=$this->htmlBody;
        $doc.=$this->getFotter();

        if($download)
        {
            @header("Cache-Control: ");// leave blank to avoid IE errors
            @header("Pragma: ");// leave blank to avoid IE errors
            @header("Content-type: application/octet-stream");
            @header("Content-Disposition: attachment; filename=\"$this->docFile\"");
            echo $doc;
            return true;
        }
        else 
        {
            return $this->write_file($this->docFile,$doc);
        }
    }

    /**
     * Parse the html and remove <head></head> part if present into html
     */

    function _parseHtml($html)
    {
        $html=preg_replace("/<!DOCTYPE((.|\n)*?)>/ims","",$html);
        $html=preg_replace("/<script((.|\n)*?)>((.|\n)*?)<\/script>/ims","",$html);
        preg_match("/<head>((.|\n)*?)<\/head>/ims",$html,$matches);
        $head=$matches[1];
        preg_match("/<title>((.|\n)*?)<\/title>/ims",$head,$matches);
        $this->title = $matches[1];
        $html=preg_replace("/<head>((.|\n)*?)<\/head>/ims","",$html);
        $head=preg_replace("/<title>((.|\n)*?)<\/title>/ims","",$head);
        $head=preg_replace("/<\/?head>/ims","",$head);
        $html=preg_replace("/<\/?body((.|\n)*?)>/ims","",$html);
        $this->htmlHead=$head;
        $this->htmlBody=$html;
        return;
    }

    /**
     * Write the content int file
     *
     * @param String $file :: File name to be save
     * @param String $content :: Content to be write
     * @param [Optional] String $mode :: Write Mode
     * @return void
     * @access boolean True on success else false
     */

    function write_file($file,$content,$mode="w")
    {
        $fp=@fopen($file,$mode);
        if(!is_resource($fp))
            return false;
        fwrite($fp,$content);
        fclose($fp);
        return true;
    }

}

Было бы здорово, если кто-нибудь может помочь мне решить эту ошибку .. большое спасибо .. PS

Ответы [ 3 ]

2 голосов
/ 26 июня 2011
 Undefined offset: 1

означает, что вы пытаетесь прочитать ключ массива '1', когда его нет. Это, вероятно, означало бы, что полученная вами строка находится здесь:

 $head=$matches[1];

или

 $this->title = $matches[1];

То есть ваши совпадения не содержат элемент [1], поэтому вы ничего не «ударили» там.

Руководство по отладке:

  • удалить все после $head=$matches[1];
  • Проблема все еще там: вы нашли свою линию. Это не? Это вторая строка.
  • В случае проблемы preg_match введите $html (или $head) переменные, чтобы увидеть их содержимое. Имейте в виду, что они не будут отображаться в браузере, если они HTML, поэтому проверьте источник или сделать это в командной строке.
  • Постарайтесь выяснить, есть ли у вашего var содержимое, которое вы ожидаете, и можете ли вы действительно соответствовать его регулярному выражению. Если нет: исправьте выражение или переменную. если так:
  • Создайте тестовый файл с содержимым переменной, жестко закодированным в вашем preg_match. Проблема все еще там? может быть var_dump ваш $matches чтобы быть уверенным
  • Если проблема все еще существует (вы, вероятно, уже столкнулись с проблемой, но тем не менее): опубликуйте тестовый код (этот последний тестовый файл с жестко закодированным preg_match, который доставляет неприятности) и спросите, где вы его неправильно поняли.

Итог: отправьте МИНИМАЛЬНЫЙ кусок кода, где он все еще идет не так. Вы обязательно найдете проблему на пути создания этой минимальной проблемы, но если вы этого не сделаете, нам будет намного легче помочь вам.

1 голос
/ 26 июня 2011

Нигде в вашем коде вы фактически не проверяете, что вам удалось успешно открыть документ для анализа, также вы можете показать нам больше кода и даже не проверить, есть ли в $matches какое-либо содержимое.Первое, что я предлагаю вам сделать, - это отформатировать код, чтобы его было легче читать, а затем взглянуть на некоторые операторы if, чтобы убедиться, что все установлено.Только второй совет сэкономит вам бесчисленные часы в будущем.

Также помните, что массивы начинаются с [0], поэтому, если вы знаете, что в совпадениях будет храниться только одна вещь, попробуйте изменить *От 1005 * до $matches[0]

0 голосов
/ 28 июня 2011

Я собираюсь пойти дальше и сказать, что ваша проблема в том, что у вас нет хороших сообщений об ошибках, а не то, что у вас неопределенный индекс.

Следуйте по пути, чтобы добраться до этой точки:

  1. $head=$matches[1]; - неопределенный индекс.
  2. $matches извлекается путем поиска head некоторого HTML-кода, который анализируется с помощью регулярного выражения (* ОГРОМНО * Кстати, нет-нет. Вам действительно стоит заглянуть в настоящий HTML-парсер)
  3. Это происходит из-за проблем с любыми вызовами _parseHtml.
  4. _parseHtml вызывается createDoc.
  5. Вы передаете "<h1>Testing data </h1>" как HTML.

Все, что дано, О КУРСЕ, которое вы получаетеиндекс не найден, вы не передаете правильный HTML, поэтому он не может его преобразовать.Попробуйте "<html><head></head><body><h1>Testing data </h1></body></html>" (примечание: ваш класс не принимает <head /> в качестве допустимого тега заголовка ... это проблема).

И есть другие области, где этот класс может быть улучшен.

  1. Вы используете ООП в стиле PHP4.Если только PHP4 не является частью функциональной спецификации.это большой нет-нет.Вы хотите, чтобы _parseHtml был приватным ...
  2. В какой-то момент я заметил это:EOH;return $ return; `Проблема в том, что Heredoc не допускает закрытые отступы .Это большими красными буквами.Я думаю, что они это имеют в виду.
  3. createDocFromURL не допускает https
  4. $doc.=$this->htmlBody;createDoc) не согласуется с кодом, непосредственно предшествующим и следующим за ним - все работаетс get<value> и эта строка является прямым доступом к свойству.
  5. У вас есть af ot ter в вашем классе (опечатка в getFotter)
  6. ЕслиPHP 5 является опцией, вы должны использовать file_put_contents в write_file.
  7. У вас есть противоречивые имена методов - write_file против getHeader

I'mне пытается сбить вас с толку, но большинство из них имеют большой потенциал для возникновения проблем в будущем.Вы действительно должны рассмотреть их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...