Intereting Posts
Контроль версий: весь сайт или просто штуки? Как показать пользовательскую таксономию с использованием настраиваемого шаблона Понимание apply_filters WooCommerce изменяет количество столбцов на главной странице Переопределить категорию постоянной ссылки в соответствии со старыми ссылками, отличными от WordPress? Виджет застрял в определенном месте при перетаскивании вниз Функции the_password_form не работают вместе Переписывание URL-адресов изображений с динамического на оригинальное показать текст Если зарегистрирован специальный пользователь RSS-канал для динамического набора условий пользовательской таксономии Разная компоновка на странице поиска в зависимости от должности категории WordPress внезапно прекратит сохранять файлы, загруженные моим кодом (выполняется в nopriv ajax) Удалить родителей из постоянной иерархической таксономии Описание тега не показывает гиперссылку Слияние плагинов сообщений?

Ошибка синтаксиса, неожиданный «класс» (T_CLASS) в строке 1 после обновления до php 5.6.4

После обновления до 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('dm 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");') ); 

Ошибка о чем-то в строке 1, которая на самом деле находится на более поздней позиции, означает, что PHP не распознает ваши окончания строк.

Существует три способа кодирования окончания строки, и PHP понимает только два из них:

  1. LF или \n , подача линии, U + 000A
  2. CR, или \r , Возврат каретки, U + 000D
  3. CRLF, или \r\n , комбинация первого и второго

LF по умолчанию используется в таких системах, как UNIX, Linux и Mac OS X (с 2001 года).
CRLF является значением по умолчанию в Windows, унаследованным от CP / M. В настоящее время LF также работает с Windows, нет необходимости использовать CRLF.
CR был стандартным для Classic Mac OS до 2001 года.

PHP не понимает 2., только CR, что понятно, потому что никто больше этого не использует. Ну, почти никто. Есть еще некоторые редакторы, которые не только позволяют эту устаревшую кодировку окончания строки, они даже не предупреждают своих пользователей, когда они ее используют.

Установите для вашего редактора только LF, и вы в безопасности. К сожалению, стандарты кодирования WordPress об этом молчат.

Ответ @ tosho слишком хорош.

То, что только что произошло, – это парсер PHP, который пытается разобрать этот файл и сначала создает токены , и путается с первым class токенов, потому что парсер для этой версии PHP не может хорошо работать с символами.

Случается, что и другие невидимые символы Юникода могут разорвать парсер. Главное, что вы просто не можете понять проблему из редактора, если вы не откроете редактор Hex.

Характер BOM также (реквизит @MarkKaplun) может создавать проблемы. Есть некоторые символы юникода n-dash, которые могут выглядеть так же, как (минус), и вы можете поцарапать свою голову в течение нескольких дней.

В этом случае, когда вы подтвердили, что символ возврата каретки был вашей проблемой.

Но это зависит от версии PHP. Я проверил ваш код на PHP 7 и проблем не обнаружено.

Я заметил, что редактор WPSO обрезает символ \r , и я добавил его вручную при тестировании.

введите описание изображения здесь введите описание изображения здесь

Мораль истории.

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

Но также исправить окончание для файлов, отличных от 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, которые могут читать файлы.