web-dev-qa-db-ja.com

構文エラー、php 5.6.4にアップグレードした後の1行目の予期しない 'class'(T_CLASS)

Php 5.6.4にアップグレードした後、私のウィジェットファイルは次のようになります。

Parse error: syntax error, unexpected 'class' (T_CLASS) in /home/path/fss-widgets.php on line 1

私は誤解しています - 数時間の研究では何も得られませんでした。この問題では、問題は引用符で囲まれたり、エスケープされたり、その他に予想されることではないように思われ、コードは私には問題ないように見えます。

<?php

/*
Plugin Name: FSS Vacancy Widget
Plugin URI: http://www.url.com/
Description: Shows recent vacancies
Author: Name
Version: 1.0
Author URI: http://www.url.com/
*/

class FSSVacancyWidget extends WP_Widget
{
  function FSSVacancyWidget()
  {
    $widget_ops = array('classname' => 'FSSVacancyWidget', 'description' => 'Displays Recent FSS Jobs on the homepage and all other pages' );
    $this->WP_Widget('FSSVacancyWidget', 'FSS Vacancies', $widget_ops);
  }

  function form($instance)
  {
    $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
    $title = $instance['title'];
    $fss_numposts = $instance['fss_numposts'];
    $fss_vacurl = $instance['fss_vacurl'];
    $fss_morevac = $instance['fss_morevac'];
?>
    <p><label for="<?php echo $this->get_field_id('title'); ?>">Title: <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label></p>
    <p><label for="<?php echo $this->get_field_id('fss_numposts'); ?>">Number of Posts (Default is 10): <input class="widefat" id="<?php echo $this->get_field_id('fss_numposts'); ?>" name="<?php echo $this->get_field_name('fss_numposts'); ?>" type="text" value="<?php echo attribute_escape($fss_numposts); ?>" /></label></p>
    <p><label for="<?php echo $this->get_field_id('fss_vacurl'); ?>">Vacancy URL: <input class="widefat" id="<?php echo $this->get_field_id('fss_vacurl'); ?>" name="<?php echo $this->get_field_name('fss_vacurl'); ?>" type="text" value="<?php echo attribute_escape($fss_vacurl); ?>" /></label></p>    
    <p><label for="<?php echo $this->get_field_id('fss_morevac'); ?>">More Vacancies Title: <input class="widefat" id="<?php echo $this->get_field_id('fss_morevac'); ?>" name="<?php echo $this->get_field_name('fss_morevac'); ?>" type="text" value="<?php echo attribute_escape($fss_morevac); ?>" /></label></p>   

<?php
  }

  function update($new_instance, $old_instance)
  {
    $instance = $old_instance;
    $instance['title'] = $new_instance['title'];
    $instance['fss_numposts'] = $new_instance['fss_numposts'];
    $instance['fss_vacurl'] = $new_instance['fss_vacurl'];
    $instance['fss_morevac'] = $new_instance['fss_morevac'];
    return $instance;
  }

  function widget($args, $instance)
  {
    extract($args, EXTR_SKIP);

    /* User-selected settings. */
   $fss_numposts = $instance['fss_numposts'];
   $fss_vacurl = $instance['fss_vacurl'];
   $fss_morevac = $instance['fss_morevac'];

    echo $before_widget;
    $title = empty($instance['title']) ? ' ' : apply_filters('widget_title', $instance['title']);

    if (!empty($title))
      echo $before_title . $title . $after_title;;

    echo "<ul class='items'>";

    query_posts( array( 'showposts' => $fss_numposts ) );
    if ( have_posts() ) : while ( have_posts() ) : the_post();
    echo "<li><a href='".get_permalink()."'><span class='job-title'>".get_the_title()."</span><span class='job-date'>".get_the_date('d m Y')."</span></a></li>";

    endwhile; endif; wp_reset_query();

    echo "</ul>";
    echo"<a href='".$fss_vacurl."' class='view'>".$fss_morevac."</a>";

    echo $after_widget;
  }

}
add_action( 'widgets_init', create_function('', 'return register_widget("FSSVacancyWidget");') );
5
toomanyairmiles

1行目 に実際に遅い位置にあるものに関するエラーは、PHPがあなたの行末を認識しないことを意味します。

行末をエンコードする方法は3つあり、PHPはそのうちの2つしか理解できません。

  1. LF、または\n、改行、 U + 000A
  2. CR、または\r、キャリッジリターン、 U + 000D
  3. CRLF、または\r\n、1番目と2番目の組み合わせ

LFは、UNIX、Linux、およびMac OS Xなどのシステムではデフォルトです(2001年以降)。
CRLFはWindowsのデフォルトで、 CP/M から継承されます。 WindowsではLFだけで動作するようになりました。CRLFを使用する必要はもうありません。
CRは、2001年まで Classic Mac OS のデフォルトでした。

PHPは2.、CRのみを理解していません。これは理解できるものです。これは誰も使用していないためです。ええ、ほとんど誰もいません。まだ使われていない行末エンコーディングを許可するだけでなく、ユーザーが使用しているときにユーザーに警告することすらしない編集者もいます。

エディタをLFのみを使用するように設定すれば、安全です。残念なことに、 WordPress Coding Standards はこれについて何も述べていません。

8
fuxia

@toshoの答えは良すぎる。

ちょうど起こったのはPHPパーサーがそのファイルを解析し、最初に tokens を作成しようとし、最初のトークンclassと混同され、そのバージョンのパーサーのためにPHPは\r文字ではうまく機能しません。

他の見えないUnicode文字もパーサーを破壊する可能性があります。主なことは、16進エディターを開かない限り、エディターから問題を理解できないことです。

BOM文字(@MarkKaplunの小道具)も問題を引き起こす可能性があります。 -(マイナス)のように見えるUnicodeのnダッシュ文字がいくつかあり、何日も頭を悩ますことができます。

この場合、\r復帰文字が問題であることが確認されました。

しかし、これはPHPバージョンに依存しています。 PHP 7でコードをテストしましたが、問題は見つかりませんでした。

WPSOエディターが\r文字をトリミングすることに気付き、テスト時に手動で追加しました。

enter image description hereenter image description here

物語の教訓。

プロジェクトのregex replaceを使用して、エディターから行末を修正します。

ただし、非PHPファイルの末尾も修正します。

define('CR', "\r");          // Carriage Return: Classic Mac
define('CRLF', "\r\n");      // Carriage Return and Line Feed: Windows
define('LF', "\n");          // Best: Unix, Linux, Mac, Windows


function fix_endings($s) {
    // Convert all line-endings to the Best format.
    $s = str_replace( CRLF, LF, $s );
    $s = str_replace( CR, LF, $s );
    // Don't allow out-of-control blank lines
    $s = preg_replace( "/\n{2,}/", LF . LF, $s );
    return $s;
}

行末は非常に重要であり、セキュリティに影響する場合があります。 PHPパーサーが一部の文字で失敗した場合、ファイルを読み取るPHP関数も推測される可能性があります。

2
prosti