Архив июля 2008

Работа с формами

Суббота, 26 июля, 2008

Работа с формами — одна из самых типинчых задач при Web-программировании. Чаще всего в форме требуется либо ввести новую информацию о каком-либо объекте, либо отредактировать уже существующую, причем для нового объекта есть значения полей по умолчанию. Существует много разных способов фомирования форм, но наиболее красивым решением является следующий: форма хранится в обычном HTML, в поля прописаны значения по умолчанию. Перед выводом формы в броузер скрипт формирует хеш со значениями полей, которые нужно показать пользователю, после чего вызывает функцию, которая парсит форму и заменяет значения по умолчанию на значения из этого хеша (имя поля  в хеше должно совпадать с именем поля в форме).

Вот вариант реализации такой процедуры (параметры: первый параметр — html-код с формой, второй параметр — хеш с данными, третий параметр — хеш с дополнительными опциями для select’ов, которые будут дописаны к уже существующим в статике в процессе парсинга selectа, ключ соответствует имени select-поля, значение — хешу вида имя_опции=>значение_опции):

/** Функция установки значений полей форм в соответствии с параметрами в хеш-массиве data.
(Ключи массива должны соответствовать именам полей.)
Если ключ в массиве отсутствует, поле остается без изменений
(таким образом, имеет смысл прописывать в качестве значений полей значения по умолчанию).
**/
function cmsmain_html_set($html,$data,$params=false) {
  $count = preg_match_all('|(<input[^>]+?>)|is',$html,$inputs);
  for ($i=0; $i<$count; $i++) {
    $name=_cmsmain_html_getparam($inputs[0][$i],'name');
    if (($newvalue=_cmsmain_html_data($data,$name))!==false) {
      $newstr=false;
      $value=_cmsmain_html_getparam($inputs[0][$i],'value');
      $type=_cmsmain_html_getparam($inputs[0][$i],'type');
      if ($type=="radio" || $type=="checkbox") {
        if ($value==$newvalue) {
          $newstr=$inputs[0][$i];
          if (strrpos($newstr,'/>')===strlen($newstr)-2) $newstr=str_replace('/>',' checked="checked"/>',$newstr);
          else $newstr=str_replace('>',' checked>',$newstr);
        }
	      else {
	        $newstr=preg_replace('|\s+checked(=\S+?)?([\s/>])|s','$2',$inputs[0][$i]);
	      }
      }
      else {
        if (preg_match('|\s+value=[\'"]?'.$value.'[\'"]?([\s/>])|is',$inputs[0][$i])) {
          $newstr=preg_replace('|\s+value=[\'"]?'.$value.'[\'"]?([\s/>])|is',' value="'.htmlspecialchars($data[$name]).'"$1',$inputs[0][$i]);
        }
        else $newstr=preg_replace('|(/?>)$|s',' value="'.$newvalue.'"$1',$inputs[0][$i]);
      }
      if ($newstr) $html=str_replace($inputs[0][$i],$newstr,$html);
    }
  }
  $count = preg_match_all('|(<textarea[^>]+?>)(.*?)</textarea>|is',$html,$textareas);
  for ($i=0; $i<$count; $i++) {
    $name=_cmsmain_html_getparam($textareas[1][$i],'name');
    if (($newvalue=_cmsmain_html_data($data,$name))!==false) {
      $newstr=$textareas[1][$i].$newvalue.'</textarea>';
      $html=str_replace($textareas[0][$i],$newstr,$html);
    }
  }
  $count = preg_match_all('|(<select[^>]+?>)(.*?)</select>|is',$html,$selects);
  for ($i=0; $i<$count; $i++) {
    $name=_cmsmain_html_getparam($selects[1][$i],'name');
    if (isset($params[$name]) && is_array($params[$name])) {
      $newselects = '';
      foreach ($params[$name] as $key=>$value) {
        if ($value=='') $value=$key;
        $newselects.='<option value="'.htmlspecialchars($key).'">'.htmlspecialchars($value).'</option>';
      }
      $newbigstr=str_replace($selects[2][$i],$selects[2][$i].$newselects,$selects[0][$i]);
      $selects[2][$i].=$newselects;
    }
    else $newbigstr=$selects[0][$i];
    if (($newvalue=_cmsmain_html_data($data,$name))!==false) {
      $optcount = preg_match_all('|<option([^>]+?)>(.*?)<|is',$selects[2][$i].'<',$options);
      for ($j=0; $j<$optcount; $j++) {
        $value=_cmsmain_html_getparam($options[1][$j],'value');
        if ($value==$newvalue) {
          $newstr=$options[0][$j];
          $newstr=preg_replace('|(<option[^>]+?)>|s','$1 selected="selected">',$newstr);
        }
	      else $newstr=preg_replace('|\s+selected(=\S+?)?([\s/>])|s','$2',$options[0][$j]);
        $newbigstr=str_replace($options[0][$j],$newstr,$newbigstr);
      }
      $html=str_replace($selects[0][$i],$newbigstr,$html);
    }
  }
  return $html;
}

/** Извлечение параметра из html-тега. **/
function _cmsmain_html_getparam($input,$param) {
  if (!preg_match('|\s+'.$param.'="(.*?)"|is',$input,$matches)) {
    if (!preg_match('|\s+'.$param.'=\'(.*?)\'|is',$input,$matches)) {
      if (!preg_match('|\s+'.$param.'=(\S+?)|is',$input,$matches)) { $matches[1]=''; _dbg('Fuck!'); }
    }
  }
  return $matches[1];
}

/** Извлекает данные из массива и применяет к ним htmlspecialchars.
На данный момент не поддерживается обработка спецсимволов (типа [] для вложенных массивов)
**/
function _cmsmain_html_data($data,$name) {
  if (isset($data[$name])) return htmlspecialchars($data[$name]);
  else return false;
}

Код обновлен 4 августа 2008 года.

Прохождние валидации с noindex

Вторник, 15 июля, 2008

Существует способ пройти валидацию с noindex. Для этого тег открывающие и закрывающие теги noindex помещаются в секцию cdata (работать это будет, естественно, только в XHTML), а затем обе секции cdata помещаются в невидимый div или span:

<span style="display: none"><![CDATA[<noindex>]]></span>
То, что запрещено к индексации
<span style="display: none"><![CDATA[</noindex>]]></span>

Идея позаимствована вот отсюда: http://www.seoburg.ru/2007/01/25/162/

Сервис для проверки времени загрузки сайта

Суббота, 12 июля, 2008

http://www.octagate.com/service/SiteTimer/ — сервис для проверки времени загрузки сайта. Позволяет увидеть время начала и окончания загрузки каждого URL (т.е. самой Web-страницы, Iframes, Frames, файлов JavaScript, CSS и графики), а также загружаемый размер и использование сжатия. Сервис весьма удобен при проверке разработанных сайтов и выявлению причин медленной загрузки (т.е. виноват ли скрипт, генерирующий страницу, Web-сервер, медленные DNSы или что-то еще), однако неизвестно, используется ли тот же порядок загрузки, что и в броузерах.

Подсветка синтаксиса с помощью JavaScript

Вторник, 8 июля, 2008

Иногда требуется подсвечивать синтаксис кусков программного кода на Web-страницах. Стандартными средствами это удается делать только для PHP (при условии, что страница генерируется с помощью самого PHP), а для других языков такой возможности не имеется.

Однако существует решение GoogleCode Pretify, которое позволяет избавиться от этой проблемы. Скачать его можно здесь: http://google-code-prettify.googlecode.com/files/prettify-small-5-Jul-2008.zip, использовать следующим образом: подключить файлы prettify.css и pretty.js, написать нужный код в теге code c классом class=”prettyprint” и повесить вызов функции prettyPrint() в обработчик onLoad. В итоге получается примерно такой код:

<link href="prettify.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="prettify.js"></script>
<body onLoad="prettyPrint()"><code clas="prettyprint">//Sample code</code>

В настоящее время поддерживаются языки C/C++, Java, Python, Bash, SQL, HTML, XML, CSS, Javascript, а также с некоторыми ограничениями Perl, PHP, Ruby.

Скрипт определяет тип синтаксиса сам, но имеется возможность помочь ему, указав класс явно (т.е. вместо class=”prettyprint” написать class=”prettyprint класс_языка”).

Проверка SMTP-сервера на open relay

Вторник, 1 июля, 2008

Автоматически проверить почтовый сервер на то, что он не является open relay (т.е. не предоставляет возможности делать несанкционированные рассылки) можно по адресу.

http://www.abuse.net/relay.html

Данный сервис проверяет несколько наиболее распространенных ошибок при конфигурации почтовых серверов (например, попытки выдать себя за локального пользователя).

(Запись обновлена 30 июня 2009 года).


Rambler's Top100