PHP — Блог Валерия Леонтьева https://valera.ws Место публикации личных заметок. Технологии, управление, бизнес, жизнь Sun, 02 Feb 2014 12:11:19 +0000 ru-RU hourly 1 https://wordpress.org/?v=5.6.2 https://valera.ws/wp-content/uploads/2020/02/favicon.png PHP — Блог Валерия Леонтьева https://valera.ws 32 32 Архитектура веб приложений: интерьер (видео-лекция) https://valera.ws/2014.02.02~web-applications-architecture-interior/ https://valera.ws/2014.02.02~web-applications-architecture-interior/#respond Sun, 02 Feb 2014 12:06:30 +0000 http://valera.ws/?p=734 Архитектура веб-приложений: интерьерРассказ о возможной внутренней архитектуре ориентированных на масштабируемость, обслуживаемость и расширяемость веб-приложений, разрабатываемых на PHP или подходящих для Веба языках программирования. Реализация компонентного подхода внутри приложения, фунционального разделения кода, введение уровней абстракции копонентов.

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

]]>
https://valera.ws/2014.02.02~web-applications-architecture-interior/feed/ 0
Архитектура веб приложений: экстерьер (видео-лекция) https://valera.ws/2014.01.18~web-applications-architecture-exterio/ https://valera.ws/2014.01.18~web-applications-architecture-exterio/#respond Sat, 18 Jan 2014 17:34:57 +0000 http://valera.ws/?p=730 Читать далее Архитектура веб приложений: экстерьер (видео-лекция) ]]> Архитектура веб-приложений: экстерьерРассказ о популярной универсальной архитектуре стека, в котором работает веб-приложение. Само приложение может быть написано на любом интерпретируемом языке с использованием любого фреймворка фреймворков. В данном случае это не важно, так как архитектура программной инфраструктуры — технологического стека, в котором оно работает, отличается мало.

Обсуждается путь запроса пользователя до и внутри сервера, его обработка и возврат ответа. Затрагиваются вопросы состояния приложения — работы с хранилищами, кэширования.

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

Смотрите в полноэкранном режиме.

]]>
https://valera.ws/2014.01.18~web-applications-architecture-exterio/feed/ 0
Передача имени сайта скрипту через cron (crontab) https://valera.ws/2011.01.13~sitename-php-from-cron/ https://valera.ws/2011.01.13~sitename-php-from-cron/#comments Thu, 13 Jan 2011 20:32:58 +0000 http://valera.ws/?p=530 Читать далее Передача имени сайта скрипту через cron (crontab) ]]> PHP-скриптВчера на stackoverflow заметил вопрос о том, как передать скрипту через крон адрес сайта, если скрипт может выполняться «под разными сайтами». Это довольно интересный вопрос, и есть много вариантов решения. Сам решал его не так давно, а раз тема интерисует и других, решил об этом написать.

Немного подробнее о самом вопросе. Зачастую встречаются сайты, работающие на одной кодовой базе на одном сервере, но, при этом, на разных доменах. При схожем внешнем виде на этих сайтах содержится разная информация в разном дизайне.

Самый простой пример таких сайтов — это локализованные версии одного сайта на разных языках. У меня в практике — это тематические форумы для разных групп.

Разделение этих сайтов обычно происходит через конфиги. Именно конфиг определяет все детали, уникальные для каждого сайта.

При запуске обработки пользовательского HTTP-запроса скриптам необходимо определить, какому именно домену предназначен запрос, и выбрать соответствующий конфиг. В PHP это довольно просто сделать: заглянуть в переменную $_SERVER[‘SERVER_NAME’]. В других языках программирования под веб, думаю, примерно так же просто.

По имени серевера определяется нужный конфиг и оттуда берутся все необходимые настройки. Все просто.

Но когда дело доходит до вызова скриптов из cron-а (или другого планировщика), то переменная $_SERVER[‘SERVER_NAME’] будет пуста. Оно-то и понятно: никакого сервера нет, скрипт запускается напрямую через CLI. И узнать, для какого сайта вызывается скрипт, без явной передачи домена скрипту невозможно.

Самый простой способ указать домен — это прописать его аргументом командной строки. При вызове из cron-а после имени скрипта просто пишем домен, а в коде получаем его из переменной $argv глобальной области видимости.

Но этот способ не отличается элегантностью, т.к. придется определять, как запускался сайт: через веб или CLI, и в зависимости от этого искать адрес сайта в разных местах.

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

Таким образом ищем более удобный способ передать «указатель» на сайт. И находим: это переменные окружения. Среду окружения интерпретатор PHP получает оттуда, откуда он был запущен. Если скрипт запущен веб-сервером, то переменные будут получены от сервера. Если запускается скрипт через CLI, то среда будет получена от shell-а, в котором производился запуск. Повторю: запуск скриптов из cron-а — это обыкновенный запуск исполнимого файла в режиме CLI.

Теперь к конкретике. Чтобы переменная среды окружения попала из веб-сервера в PHP-скрипт (или скрипт/программу, написанную на других языках), ее надо установить (прописать). Для Апача установить переменную можно в файле .htaccess, либо в конфигах сервера (httpd.conf или конфиги виртуальных хостов). В идеале предпочтительно последнее. Но достаточно и минимального уровня доступа к .htaccess. Добивим в соответствующий конфиг строку:

SetEnv SITE_NAME site1

Чтобы определить переменную среды при запуске в режиме CLI (php /filename), нужно ее объявить и экпортировать:

export SITE_NAME=site1;

При запуске скрипта вручную следующей командой можно запускать сам PHP. Если запуск производится cron-ом, то стоит создать скрипт, на который ссылаться из crontab:

#!/bin/bash
export SITE_NAME=site1;
php /path

Для других сайтов вместо site1 подставляются другие имена.

Остается прочитать переменную в скрипте:

echo getenv('SITE_NAME');

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

* Стоит отметить, что в случае разных «установок»1 одного и того же сайта (development, testing, production) принято это значение передавать сайту в виде тоже же переменной окружения. Как правило, конфиг в этом случае содержит очень много информации, одинаковой для всех «установок», а отличаться, например, могут только параметры доступа к БД. Тогда имеет смысл все установки считать за один сайт (хоть домены и разные), а отличающиеся параметры вынести в отдельный конфиг, зависимый от «установки».

1 — Я намеряно в последнем абзаце заменил термин «окружение приложения» (application environment: тестовое, рабочее) на «установку», чтобы не было путаницы с тем окружением, где устанавливаюся переменные.

]]>
https://valera.ws/2011.01.13~sitename-php-from-cron/feed/ 2
Делегирование обслуживания почтового домена: часть 2. Отправка почты через localhost (настройка Exim4 в Debian) https://valera.ws/2010.11.28~exim-mail-localhost/ https://valera.ws/2010.11.28~exim-mail-localhost/#comments Sun, 28 Nov 2010 19:18:55 +0000 http://valera.ws/?p=455 Читать далее Делегирование обслуживания почтового домена: часть 2. Отправка почты через localhost (настройка Exim4 в Debian) ]]> Настройка Exim и PHP mail() на примере Linux Debian

Чтобы решить проблему отказа серверов Gmail от обслуживания  при отправке большого числа писем на несуществующие адреса, используем для отправки почты из скриптов сайта локальный почтовый SMTP-сервер (MTA). Локальный сервер будет выступать в качестве mail relay. В дополнение мы откажемся от подключения из скрипта к удаленному серверу, что может быть медленно. Локальные подключения всегда должны быть быстрее и стабильнее.

Локальный сервер мы будем использовать только для отправки писем. Причем, не важно, как будет происходить отправка: непосредственно через SMTP, или с помощью MUA. Получение почты по-прежнему будет происходить с серверов Gmail.

В дистрибутиве Debian 5 по умолчанию устанавливается MTA Exim4. Он отлично подойдет для наших задач. Причем его настройка производится с помощью мастера и невероятно проста. Настроить сервер требуется на прием соединений исключительно с локального соединения. При этом не нужно поручать ему обслуживание доменов, кроме дефолтного локального (localhost).

Итак, если Exim у вас не установлен, то установим его:

# aptitude install exim4

Далее запускаем его конфигурацию:

# dpkg-reconfigure exim4-config

1. На первом шаге необходимо выбрать конфигурацию сервера. В Exim есть несколько стандартных конфигураций, предназначенных для разных случаев. Подробнее о них в мануале. Нам нужна конфигурация “internet site; mail is sent and received directly using SMTP”.

2. Далее укажите имя сервера. Оно будет передаваться в SMTP-протоколе в команде HELLO, т.е. будет видно получателям вашей почты. Лучше всего, чтобы это имя совпадало с доменом, с которого шлется почта. Например, valera.ws.

Если у вас на сервере несколько сайтов с разными доменами (см. ниже), то лучше это имя сделать нейтральным, чтобы «не палиться». Например, можно выбрать local-mail-agent.

3. Далее требуется указать, какие интерфейсы должен слушать Exim. В нашем случае удаленные подключения мало того, что не нужны, так еще и опасны: кто угодно сможет рассылать почту через ваш сервер. Указываем только 127.0.0.1.

4. Далее спрашивается, какие домены должен обслуживать сервер. Т.е. для каких доменов не нужно пересылать письма на удаленные SMTP-сервера, пользователь заберет их с этого сервера. Нам не нужно обслуживание наших доменов. Можно указать только localhost, т.к. его больше обслужить некому.

Не указывайте здесь адрес вашего сервера (подставляется по умолчанию), т.к. его обслуживание делегировано Gmail. Если его указать, то письма, отправленные на ящики вашего домена, в Gmail не попадут и останутся на сервере. Это не нужно.

5. Далее можно указать, для каких доменов сервер должен служить релеем (список через точку с запятой). Здесь не указываем ничего, так как на следующем шаге мы разрешим себе релей для всех доменов. Можете указать список ваших доменов.

6. Здесь укажем 127.0.0.1, чтобы раз-решить релей для всех запросов с локального IP.

При этой конфигурации есть один негативный момент. Если ваш сайт поломают, то злоумышленники смогут слать почту с любых доменов через ваш сервер. Если на сервере 1—2 сайта, то лучше на этом шаге оставить поле пустым, а на предыдущем шаге внести список этих доменов (для возврата на шаг назад нажмите кнопку “Cancel”). При появлении новых доменов не забывайте их заносить в конфиг. Если вы считаете свои сайты надежными, то проще всего указывать здесь 127.0.0.1.

7. Дале уточняется, является ли для нас проблемой постоянные DNS-запросы при отправке каждого письма. В 99,9% это не проблема, так что выбираем ответ на вопрос “Keep number of DNS-queries minimal (Dial-on-Demand)?” “No”.

8. Где хранить локальную почту (помните, мы указали серверу обслуживать домен localhost?) нам по сути не важно, так как этим как правило никто не пользуется. Можно выбрать вариант по умолчанию: складывать все в /var/mail.

9. Предпоследний шаг — выбор конфигурации. Хранить все в одном файле, или раскидать по множеству мелких файлов. В большой файл проще вносить большие изменения, а с мелкими проще работать в случае мелких правок. Выберите вариант на свой вкус. Я выбрал “unsplit configuration” (ответ “No”).

10. На последнем шаге укажем на какой аккаунт реального пользователя системы пересылать сообщения, отправленные на служебные аккаунты postmaster, root и т.д. Здесь имеет смысл указать ваше имя пользователя в системе.

Переконфигурировать Exim в любой момент можно тем же способом. Мастер подставит в значения по умолчанию текущие значения вашей конфигурации.

Правильная настройка SPF

Если кратко, то SPF — это способ борьбы со спамом.

Мы собираемся отправлять почту с сервера, PTR IP которого не равен одной из MX-записей сервера, а так же в большинстве случаев PTR IP не равен самому нашему домену (не всегда хостеры соглашаются менять PTR). В этом случае вероятность попадания писем в спам повышается. Но есть хороший способ ее понизить: указать правильно запись SPF нашего домена.

SPF-запись — это обыкновенная запись доменной зоны, имеющая тип TXT. Узнать текущее ее значение для домена можно с помощью команды host в Linux:

$ host -t TXT valera.ws
valera.ws TXT record currently not present

В данном примере SPF-запись не задана. Зададим ее. С моего домена почта может отправляться с серверов Gmail и с моего сервера. Для начала узнаем, какой PTR моего сайта (valera.ws):

$ nslookup valera.ws
Server:      194.224.52.4
Address:     194.224.52.4#53

Non-authoritative answer:
Name:     valera.ws
Address:  93.174.6.118

IP-адрес моего сервера 93.174.6.118. Узнаем PTR:

$ nslookup 93.174.6.118
Server:      194.224.52.4
Address:     194.224.52.4#53

Non-authoritative answer:
118.6.174.93.in-addr.arpa name = server.valera.ws.

Видно, что PTR IP, к которому привязан мой домен (IP моего сервера) — server.valera.ws.

v=spf1 a mx ptr include:_spf.google.com ~all

По порядку:

  • v=spf1 — версия SPF (первая);
  • a — разрешение отправлять почту с IP, указанного в A-записи домена (собственно с сервера, на который ваш домен ссылается);
  • mx — разрешение отправлять почту с IP, указанных в MX-записях домена (в нашем случае сервера Gmail);
  • ptr — разрешение отправлять почту с IP, PTR-запись которых содержит ваш домен (т.е. сам домен и поддомены);
  • include:_spf.google.com — подключение разрешений для серверов отправки почту Gmail (совсем не обязательно почта будет слаться с серверов, указанных в MX-записи);
  • ~all — нейтральная реакция на всю остальную почту; здесь можно указать -all, что будет значить, что почта, не попадающая под эти правила, — спам.

Если вы хотите отправлять почту с сервера, не попадающего под все эти правила, его можно указать по IP или домену PTR, например:

v=spf1 a mx ptr ptr:example.com include:_spf.google.com ~all

Запись указывается для вашего домена соответствующим образом, который определяет владелец DNS-сервера. Обычно сервером заведует хостер и предоставляет возможность вносить изменения в DNS-зоны через панель хостинга. Либо сам по запросу в саппорт меняет запись. В зональном файле должна появиться запись вида:

valera.ws.      TXT      v=spf1 a mx ptr include:_spf.google.com ~all

После обновления зоны host выдаст следующее:

$ host -t TXT valera.ws
valera.ws      TXT      «v=spf1 a mx ptr include:_spf.google.com ~all»

PHP mail()

После всей этой настройки функция mail() в PHP начнет слать почту через ваш локальный сервер на законных основаниях для антиспам-ботов. Но косяк будет в том, что в поле отправителя будет фигурировать адрес системного пользователя www-data@localdomain. Нас это не устраивает. Чтобы почта правильно слалась из mail(), необходимо использовать ее дополнительный параметр.

bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )

Именно $additional_parameters нас и интерисует. В него надо передавать реального отправителя:

mail($to, $subject, $message, $additional_headers, $additional_parameters.» -frealsender@valera.ws»);

Указывается отправитель слитно с параметром -f.

Теперь отправленные через mail() письма будут абсолютно адекватны (при условии, что вы указываете все нужные SMTP-заголовки, вроде “FROM:”, “TO:” и т.д.).

А если несколько сайтов с разными IP (настройка Exim для отправки писем с разных IP)?

Мы хотим использовать локальный SMTP-сервер для отправки почты со всех сайтов на сервере. Никаких проблем нет, если настроен Exim правильно (см. выше). Но проблема появляется, если разные сайты работают на разных IP. Мы не хотим в почте «палить» то, что все наши сайты живут на одном сервере. Но Exim по умолчанию шлет всю почту с основного (первого) IP сетевого интерфейса, а этот IP всем получателям в SMTP-заголовках “Received:” письма. Кроме того, там указывается и имя сервера, которые мы в случае с разными сайтами на сервере выбрали нейтральными.

Чтобы не «палить» IP сервера, нужно отсылать письмо на удаленный сервер с IP, равного A-записи домена сайта. Делается это несложно путем изменения конфига Exim. Внесем изменения в настройки транспорта SMTP Exim. Если вы выбрали монолитный конфиг, то нужно отредактировать файл:

# nano /etc/exim4/exim4.conf.template

Находим в файле строку “remote_smtp:” (поиск в nano — F6). Добавляем в конец этого блока:

interface = «${lookup{$sender_address_domain}lsearch{/usr/share/exim4/domain2ip}{$value}}»
helo_data = «$sender_address_domain»

Это значит, что при отправке письма нужно определить домен отправителя почты (для sender@valera.ws это valera.ws) и отправить почту с IP, к которому этот домен привязан. Само собой разумеется, что домен должен быть привязан к серверу, где установлен Exim.

Так же нужно создать файл в любом месте файл привязки доменов к IP (у домена может быть несколько IP, так что просто lookup-ить его не прокатит). Я выбрал для файла место: /usr/share/exim4/domain2ip

# nano /usr/share/exim4/domain2ip

Туда вводим наши домены по шаблону:

valera.ws: 123.123.123.123
vasya.ws: 123.123.123.124

Не забудьте дописать домен в файл в случае появления нового сайта.
Кстати, строку helo_data = «$sender_address_domain» можно добавить в файл даже если у вас один IP на все сайты. Тогда в команде HELLO SMTP-протокола (а, следовательно, и в заголовках писем) будет фигурировать ваш домен.

Идея с указанием интерфейса взята отсюда: http://www.directadmin.com/forum/showthread.php?t=36468

Проверка

Остается проверить, чтобы все ваши настройки работали верно. Для этого просто отправим письмо с локального сервера через консоль.

$ mail -a «From:feedbee@valera.ws» -s Test feedbee@gmail.com — -ffeedbee@valera.ws
Test <Ctrl-D>
Cc:

Проверяем отосланное письмо в ящике получателя:

А вот текст SMTP-протокола:

Delivered-To: feedbee@gmail.com
Received: by 10.236.109.139 with SMTP id s11cs13826yhg;
Wed, 24 Nov 2010 02:18:14 -0800 (PST)
Received: by 10.227.145.134 with SMTP id d6mr9025492wbv.195.1290593893066;
Wed, 24 Nov 2010 02:18:13 -0800 (PST)
Return-Path: feedbee@valera.ws
Received: from valera.ws (server.valera.ws [93.174.6.118])
by mx.google.com with ESMTP id b7si11085685wer.164.2010.11.24.02.18.12;
Wed, 24 Nov 2010 02:18:12 -0800 (PST)
Received-SPF: pass (google.com: domain of feedbee@valera.ws designates 93.174.6.118 as permitted sender) client-ip=93.174.6.118;
Authentication-Results: mx.google.com; spf=pass (google.com: domain of feedbee@valera.ws designates 93.174.6.118 as permitted sender) smtp.mail=feedbee@valera.ws
Received: from root by server.valera.ws with local (Exim 4.69)
(envelope-from <feedbee@valera.ws>)
id 1PLCQW-0006KD-Pc
for feedbee@gmail.com; Wed, 24 Nov 2010 10:18:12 +0000
To: feedbee@gmail.com
Subject: Test
From:feedbee@valera.ws
Message-Id: E1PLCQW-0006KD-Pc@server.valera.ws
Date: Wed, 24 Nov 2010 10:18:12 +0000

Test

P.S. Чтобы отправленная почта не попадала в спам, отправляйте письма только от имени реально существующих на серверах Gmail адресов на ваших доменах. Туда же повалятся уведомления о недоставках.

]]>
https://valera.ws/2010.11.28~exim-mail-localhost/feed/ 2
Определение версии браузера https://valera.ws/2009.09.16~browser-version-detection/ https://valera.ws/2009.09.16~browser-version-detection/#comments Wed, 16 Sep 2009 08:49:27 +0000 http://valera.ws/?p=347 Читать далее Определение версии браузера ]]> Вчера возникла задача определения версии браузера посетителя сайта, чтобы выводить сообщение об устаревшей версии браузера. Гуглинг не дал готового кода. PHP функция get_browser вообще нормально не работает. Пришлось написать PHP-код определения весии браузера самому. Итак, задача из HTTP-заголовка UserAgent получить название и версию браузера пользователя, а затем сравнить версию с некими барьерными версиями (по каждому браузеру). Если браузер старше барьерных версий, будем выводить сообщение об ошибке.

Детектить версии нужно только популярных в СНГ немобильных версий браузеров, поэтому в моем коде определяется только Opera, Firefox, Safari, Internet Explorer и Google Chrome. Если вам потребуется определить версии большего числа браузеров, код можно легко дополнить.

Чтобы не раскидывать функции по проекту, весь код я оформляю в классы. Создадим статический класс, в котором будут два метода: определение версии браузера и сравнение версии с данными барьерными версиями по каждому из браузеров. Назовем его BrowserUtils.

Класс состоит из двух методов: определение браузера и его версии и сравнении полученной версии с пороговыми версиями по разным браузерам. Использовать класс очень просто:

Единственный нюанс по коду есть у Safari. Все версии этого браузера всегда посылали в UserAgent тег Safari/build, где buld — версия их движка. Это большая первая цифра, например 528.16. Так версии Safari отображаются в Google Analytics. Но более поздние версии стали писать свою версию в теге Version. Выглядит это примерно так: Version/4.0.2.

Так как мне требовалось выводить версию пользователю, я использовал код считывания версии из тега Version, а для старых версий не детектит номер версии.

Скачать PHP-код определения версии браузера.

]]>
https://valera.ws/2009.09.16~browser-version-detection/feed/ 1
Собеседование по PHP https://valera.ws/2009.04.26~php-interview/ https://valera.ws/2009.04.26~php-interview/#comments Sun, 26 Apr 2009 17:10:42 +0000 http://valera.ws/?p=311 Читать далее Собеседование по PHP ]]> Обратите внимание: пост написан в апреле 2009 года. Сейчас у меня вопросы немного другие. Как будет время, обновлю список.

Компания, в которой я работаю, собирается искать хорошего PHP-программера. В связи с этим мне стала задача разработать план проведения собеседования. Решил подготовиться к этому и составить план-список вопросов, по которым будет проходить беседа.

Первым длом полез в гугл. Зачем делать работу, которую уже наверняка кто-то сделал? Так и оказалось, сразу нашел довольно неплохой план собеседования (ссылки внизу). Взял из него большуючасть вопросов и добавил свои.

Естественно, что вопросов программисту PHP можно задать море. Особенно учитвая, что знать надо связанные области (БД, сети, HTML и иже с ним, Linux). Смысла задать все вопросы, какие только можно, конечно нету. Задача — определить уровень специалиста, чтобы принять решение: подходит он нам или нет. По-этому выбрал наиболее подходящие на мой взгляд вопросы, по которым я смогу оценить уровень кандидата.

Кроме того, конечно не одиними вопросами можно обойтись. Следует предложить пройти небольшие тесты по практическим моментам. Об этом ниже.

Вопросы

1. PHP и основы программирования
1.1. Почему PHP?
1.2. Что такое ООП, основные принципы ООП.
1.3. Понятие абстракции, наследования, инкапсуляции и полиморфизма.
1.4. Что такое MVC?
1.5. Какие паттерны проектирования вам известны?
1.6. Под какую версию PHP писали? В чем различия между четвертой и пятой версиями?
1.7. Какими сторонними библиотеками пользовались?
1.8. Опыт работы с различными Frameworks/CMS?
1.9. Типы данных в PHP? (string, int, float, object, resource, null, bool, array)
1.10. Назовите по памяти функции для работы с массивами, строками и объектами в PHP (хотя бы по 5 штук).
1.11. Что такое сериализация?
1.12. Чем отличается абстрактный класс от интерфейса?
1.13. В каких случаях лучше использовать статические методы и классы?
1.14. Можно ли создать приватный конструктор? Зачем?
1.15. Как сказывается большое количество объектов в коде на производительность?
1.16. Что такое хэш?
1.17. Что такое область видимости переменной?
1.18. Что такое PDO? Что такое ORM?
1.19. Что такое PEAR?
1.20. Когда лучше использовать mysql_pconnect?
1.21. Обязательно ли писать ?> в конце скрипта?
1.22. Как вы отлаживаете PHP-код?
1.23. Проводили когда-нибудь оптимизацию сайтов?
1.24. Какую IDE используете? Какие использовали ранее?
1.25. Что такое unit-test? Использовали?
2. Tools
2.1. Что такое Apache? mod_rewrite? nginx?
2.2. Аббревиатуры SVN и CVS о чем-нить говорят? А Git и Mercurial?
2.3. Багтрекинг системы? BugZilla? Mantis? Redmine? JIRA?
2.4 .Моделирование, UML использовали?
2.5. Что такое SSH? Какие есть варианты авторизации при входе по SSH?
3. Data Bases
3.1. Что такое реляционная база данных? Какие есть типы БД?
3.2. Нормализация, денормализация.
3.3. SQL. Join’ы, Union. Подзапросы.
3.4. Процедуры, тригеры.
3.5. Вьюшки.
3.6. InnoDB vs MyISAM.
3.7. Какие бывают индексы в MySQL?
3.8. В чем отличие MySQL от PostgreSQL?
3.9. Что такое SQL-инъекция? Приведите пример.
4. HTML + CSS
4.1. Нарисуйте простенькую форму для отправки файла.
4.2. Что такое CSS? В чем разница между записью #my и .my? Для каких атрибутов можно указать :hover?
4.3. Расшифруй вот такую запись в CSS table#a tbody td.odd {text-decoration:inherit}?
4.4. Что такое стандарты W3C?
5. JavaScript
5.1. Как работает наследование в JS?
5.2. Чем отличается хэш от объекта? (провокационный)
5.3. А хэш от массива?
5.4. Если ли опыт работы с Jquery, ExtJS? Какие фреймворки использовались?
5.5. Что такое Ajax? Есть ли опыт работы с ним?
5.6. Использовали ли FireBug? Drag-on-fly?
5.7. Что такое замыкания и как они работают?
6. Linux
6.1. С *nix знаком? Какие дистрибутивы? Почему?
6.2. Apache, PHP и СУБД устанавливали под *nix? Настраивали? Оптимизировали?
7. Networking
7.1. Что такое уровни модели OSI? Сколько их?
7.2. По какому протоколу осуществляется передача данных в сети Интернет?
7.3. Какие вообще есть сетевые протоколы?
7.4. Расскажите, что происходит, когда в строке браузера набираешь адрес и нажимаешь Enter?
7.5. Что такое WSDL & web-services? Есть опыт работы?
7.6. Что такое SSL? Как работает HTTPS? Какой принцип работы HTTPS? Какие есть варианты авторизации HTTP?
8. Что такое XSLT, XML? Есть ли опыт работы с ними?

Как отработает код?

1)
<?php
/* Что будет выведено на экран? */
$a = ‘true’;
if( 0 == $a || $a )
{
echo ‘yes’;
}

2)
<?php
/* Что будет выведено на экран? */
$a = 10;
echo $a— — — — — — — — — — — —$a;

3)

<?php
class A {private function __construct(){throw new Exception(»);} public function A(){return array(‘a’,’b’,’c’);} public static function I(){return new A();}}
/*
Как вывести на экран именно то ‘b’, которое определено в массиве выше, используя одну команду (одну строку кода)?
*/

4)
<?php

/*
Какая строчка выведется при исполнении скрипта?
Почему исполняется или не исполняется каждое из условий?
*/
$x = 1;
if ($x == ‘1’) {
echo ‘a’;
}
if ($x == true) {
echo ‘b’;
}
if((bool)$x === true){
echo ‘e’;
}
if ($x === true) {
echo ‘c’;
}
if((int)$x === true){
echo ‘d’;
}

5)
<?php
/*
Что выведет скрипт? (запускается непосредственно)
*/
error_reporting(E_ALL);
ini_set(‘display_errors’,’0′);

print $x[0];
dddxxxx();

6)
<?php
/*
Для какой версии PHP будет работать этот скрипт?
Что выведет этот скрипт?
*/
class Test{

private $var;

function setMe($value){
$this->var = $value;
}
}

class More extends Test{
public $var;
}

$oTest = new Test;
$oMore = new More;

echo $oTest->setMe(‘foo’);

echo $oMore->setMe(‘foo’);

echo $oMore->var;

echo $oTest->var;

Тест на corp.mamba.ru

http://www.corp.mamba.ru/test/promo.phtml

Ссылки

А вот и те ссылки, которые помогли мне в составлении списка.

http://habrahabr.ru/blogs/php/21681/

http://habrahabr.ru/blogs/webdev/19964/

]]>
https://valera.ws/2009.04.26~php-interview/feed/ 15
Установка eAccelerator в Debian etch https://valera.ws/2009.01.26~eaccelerator-debian-etch/ https://valera.ws/2009.01.26~eaccelerator-debian-etch/#comments Mon, 26 Jan 2009 17:52:00 +0000 http://valera.ws/?p=278 Читать далее Установка eAccelerator в Debian etch ]]> К сожалению, пакета eAccelerator в официальных репозиториях Debian Etch нет, по этому устанавливать этот модуль приходится из исходников. О том, как это сделать, и написано ниже.

Перед установкой wAccelerator’а необходимо установить несколько требуемых для сборки пакетов:

# apt-get install build-essential php5-dev

Теперь можно скачать и установить eAccelerator по следующей схеме (убедитесь, что скачиваете последниюю версию исходников):

# cd /tmp
# wget http://bart.eaccelerator.net/source/0.9.5.3/eaccelerator-0.9.5.3.tar.bz2
# tar xvfj eaccelerator-0.9.5.3.tar.bz2
# cd eaccelerator-0.9.5.3
# phpize
# ./configure
# make
# make install

eAccelerator установлен! Теперь необходимо настроить в конфиге PHP использование eAccelerator’а. В Debian Etchконфигурационные файлы для различных расширений PHP 5 хранятся в каталоге /etc/php5/conf.d, а ссылка на этот каталог присутствует в конфигурационном файле PHP5 /etc/php5/apache2/php.ini, что означает, что все файлы из /etc/php5/conf.d считываются при запуске или перезапуске Apache. Так что все, что нам надо сделать, это создать файл /etc/php5/conf.d/eaccelerator.ini следующего содержания:

vi /etc/php5/conf.d/eaccelerator.ini

extension="eaccelerator.so"
eaccelerator.shm_size="16"
eaccelerator.cache_dir="/var/cache/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_max="0"
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
eaccelerator.shm_only="0"
eaccelerator.compress="1"
eaccelerator.compress_level="9"

(Про разлиные настройки модуля можно почитать на странице: http://www.eaccelerator.net/wiki/Settings.)

Как видно из конфигурации, каталог /var/cache/eaccelerator используется для хранения кэша опкода PHP на диске. Его необходимо создать вручную и разрешить на запись:

mkdir -p /var/cache/eaccelerator
chmod 0777 /var/cache/eaccelerator

Теперь перезагружаем Apache и eAccelerator начинает работать:

/etc/init.d/apache2 restart

При помощи функции phpinfo() убедитесь, что модуль успешно подключен и функционирует.

Исходный материал на английском: http://www.howtoforge.com/eaccelerator_php5_debian_etch

]]>
https://valera.ws/2009.01.26~eaccelerator-debian-etch/feed/ 1
Хабро́метр — новый сервис логирования и отображения значений кармы и хабросилы https://valera.ws/2009.01.14~habrometr/ https://valera.ws/2009.01.14~habrometr/#respond Wed, 14 Jan 2009 14:38:59 +0000 http://valera.ws/?p=269 Читать далее Хабро́метр — новый сервис логирования и отображения значений кармы и хабросилы ]]> Хаброметр — сервис логирования значений кармы, хабрасилы и позиции в рейтинге хабрапользователя и отображения этой информации на информерах, которые можно вставить в профиль, блог, форум и т.д.

Хаброметр feedbee Хаброметр feedbee

Хаброметр feedbee

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

Считать ли само слово «кармаграф» названием конкретного сервиса от Goodrone, либо же наименованием класса сервисов (или самого графика) — не знаю. Чтобы не заморачиваться с этим вопросом, свой кармаграф решил назвать иначе — Хаброметр. Ведь не только карму он считает и показывает, но еще хабрасилу и позицию в рейтинге (все, что выдает на данный момент API Хабра). Хаброметр отличается от Кармаграфа не смотря на визуальную схожесть дизайна основного информера. Конечно, я постарался взять все лучшее у Кармаграфа. Основное отличие Хаброметра — информеров будет несколько разных видов. Уже сейчас доступны три вида — кармаграфик, табло и минитабло.

Итак, пару слов о том что получилось. Весь сервис состоит из подсистемы сбора информации и подсистемы ее визуализации. Каждые 2 часа бот собирает информацию о значениях кармы, хабрасилы и позиции в рейтинге (я называю эти данные Хабразначениями) через API Хабра по всем зарегистрированным на сервисе пользователям. Данные сохраняются в базу. В любое время любой желающий может зайти на страницу пользователя и посмотреть историю его Хабразначений. Сейчас показывается история из 500 последних запросов (12 запросов в сутки, получается чуть больше 40 дней). В перспективе отображение определенно изменится, появится календарь. Кроме того, существуют графические информеры, на которых отображаются текущие Хабразначения юзера, максимальные и минимальные значения за время мониторинга и график кармы (наличие определенных компонентов зависит от типа (размера) информера).

Все скрипты написаны на PHP, СУБД используется MySQL (пока во всяком случае). Для рисования используется ImageMagick. Для запуска по расписанию — Cron.

Работает сервис на моем сервере (server.valera.ws), который, к слову, не очень мощный и может не выдержать хабраэффекта. Кстати, с технической точки зрения есть одно существенное отличие работы Хаброметра от Кармаграфа — информеры рисуются не по расписанию после скачки свежих данных, а при первом запросе на отображение информера после обновления данных. Другими словами, после прорисовки информера он кэшируется. Сама прорисовка происходит очень быстро. А кэш чистится после скачки свежих данных. Это позволяет разнести пиковую нагрузку на прорисовку свежих информеров во времени. К тому же, не все зарегистрированные юзеры вообще где-то разместят информеры, а тем более не разместят информеры сразу всех типов. Так что разовая прорисовка всех информеров была бы излишней.

Естественно сервис предоставляется «как есть» и бесплатный для использования. Код Хаброметра я собираюсь открыть, но несколько позже. Сначала требуется отладить его работу, исправить ошибки (которые там наверняка найдутся). Код будет открыт под лицензией GPL 3.

Сейчас сервис работает в режиме beta-тестирования. Буду рад вашим отзывам, багрепортам на e-mail feedbee@gmail.com. В первую очередь хочется добиться стабильности работы и оптимизации ресурсозатрат сервиса. Ну а далее уже заботиться об удобстве пользования.

Первым делом постараюсь доделать запланированные виды информеров. Это 31х31, 88х31 и 350х20. Так же надо будет что-то придумать с расширением цветовых гамм. Когда будет время, поработаю над дизайном страниц сервиса.

P.S. Сайт сервиса (описание системы и бота): http://habrometr.server.valera.ws.

P.S.S. Домен такой выбирал не специально, так случилось что server.valera.ws != valera.ws. Потому такой длинный.

P.S.S. Если из-за хабраэффекта накроется мой сервер, уже не кидайте много камней в огород. Пока не было возможности испытать его под нагрузкой.

]]>
https://valera.ws/2009.01.14~habrometr/feed/ 0
Локальная офисная версия сайта https://valera.ws/2008.12.06~office-website/ https://valera.ws/2008.12.06~office-website/#respond Sat, 06 Dec 2008 14:05:24 +0000 http://valera.ws/?p=213 Читать далее Локальная офисная версия сайта ]]> Часто в компаниях есть штатные редакторы, которые работают с некими сайтами этой, принадлежащими ей — наполняют их контентом, модерируют и т.д. Обычно редакторы вместе с обычными пользователями пользуются одной версией сайта, которая располагается на хостинге в сети. Но это не оптимально, так как лишний трафик (прежде всего HTML-код страниц, рисунки, css) гуляет с сервера на офис, занимая внешний канал компании и тратя трафик веб-сервера. При мдленном внешнем канале тратится так же и время редакторов.

В идеале, в данном случае передавать необходимо только добавляемые и получаемые данные, так как весь антураж может быть сохранен и доступен в пределах офиса локально.

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

В принципе это обычная схема для балансировки нагрузки на фронтэнд (web-сервер). Практику много фронтэндов — один бэкэнд (база) применяют довольно часто, а следующий этап разделения нагрузки (когда уже СУБД не выдерживает напора) — кластеризация серверов баз данных. Но это лирическое отступление.

Следуюет учесть три нюанса. Во-первых, так как сервера у нас теперь два, время на них может быть разное. Следовательно при записи в базу временные показатели будут для серверов расходиться и может возникнуть путаница. Чтобы этого избежать, проще всего брать время из СУБД. Делать это надо естественно 1 раз за запрос (кэшировать), а не при каждой необходимости (при условии, что запрос выполняется не более 1 секунды; если больше, значит ваша система нуждается в оптимизации). Таким образом время на всех серверах будет синхронизировано по времени на сервере с СУБД.

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

Решить эту проблему можно через подключение к СУБД по защищенному SSL-протоколу. Популярные СУБД поддерживают SSL (MySQL, PgSQL). Подключение клиента к серверу через SSL поддерживают родные C API этих СУБД, и PHP MySQL/PgSQL API тоже. Но SSL не поддерживается PDO (во всяком случае я не нашел информацию о поддержке), который в настоящее время очень популярен и который следует использовать. По этому вариант подключения к базе через SSL отпадает.

Остается другой, довольно простой для использования и сложный для настройки вариант — перегон трафика между офисом и хостингом через VPN. Сам VPN я уже описывал в своем блоге. После поднятия VPN-тоннеля необходимо прописать роут на IP вашего сервера (того сервера, где находится СУБД) через виртуальный интерфейс VPN-соединения. Таким образом весь трафик между PHP и СУБД будет ходить по безопасному зашифрованному каналу.

Третий нюанс заключается в кэшировании. Часто кэш некоторых элементов заводят пожизненно (или на долгое время), а сбрасывается он только при изменении данных редактором. В этом случае, при внесении изменений на одном из серверов, кэш не сбросится на втором и на неопределенный срок там останется неактуальная информация. Эта проблема решается через изменение стратегии кэширования, либо использование общего сервера кэширования и выходит за рамки данной статьи. Если именно этот вопрос для вас остается актуальным, ищите информацию в гугле, т.к. та же самая проблема существует при балансировке нагрузки путем «размножения» фронэндов.

Когда все проблемы решены, все что остается делать — это следить за тем, чтобы версии скриптов на серверах в сети и на офисе были одинаковыми, чтобы не повредить базу.

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

]]>
https://valera.ws/2008.12.06~office-website/feed/ 0
Статистика Google Analytics на вашем сайте https://valera.ws/2008.11.30~googleanalytics/ https://valera.ws/2008.11.30~googleanalytics/#comments Sun, 30 Nov 2008 14:16:45 +0000 http://valera.ws/?p=207 Читать далее Статистика Google Analytics на вашем сайте ]]> Один добрый хабрапользователь Andex написал на Хабре статью о том, как на свой сайт экспортировать статистику с Google.Analytics. Подробности читайте в соответствующем блоге. Все замечательно работает (на момент 30 ноября 2008 года), и хорошо выглядит даже дефолтовый набор отчетов, который автор делал для себя. Но есть один недостаток для меня, который я исправил.

Но обо всем по порядку. Для начала прочитайте статью Andex’а и «заведите» статистику на web-сервере.

Если во время установки что-то не заработало, читайте комментарии.

У меня возникла такая проблема: если сходу ошибиться с паролем, то система обратиться к гуглу с неправильным паролем столько раз, сколько отчетов экспортируется. В дефалтном варианте это 8 раз. После этого гугл естественно будет требовать от вас ввода каптчи, чтобы убедиться, что вы не подбираете пароли. А возвращать в этом случае он будет временный редирект (Temporary redirect). Его вы в логе и увидите, при этом stat.php будет вывалить нутисы про Undefined index’ы. В этом случае, надо подождать минут 20, а потом повторно запросить статистику, и все будет хорошо :)

Что меня не устроило в дефалтовых отчетах? Только то, что графики по посетителям и по посещениям были разделены. Вместо того, чтобы на одном графике сделать 3 кривых, было сделано 2 графика по 2 кривых (посетители + просмотры, посещения + просмотры).

Я решил это исправить. Но исправить так, чтобы ковырять готовый код по минимуму для простоты и быстроты решения, и для совместимости с потенциальными будущими апдейтами.

Итак, что нужно сделать? Нужно составить новый сводный отчет (*.csv), в котором будут храниться объединенные данные по посетителям, посещениям и просмотрам. И нужно сделать *settings.xml-файл, в котором будут настройки визуализации нового графика.

Генерацию сводного отчета я вынес в функцию. Она берет два отдельных отчета и составляет из них общий:

function makeFull($postfix = '')
{
	$fvisits = fopen($GLOBALS["path"] . "visits$postfix.csv", 'r');
	$fvisitors = fopen($GLOBALS["path"] . "visitors$postfix.csv", 'r');
	$ffull = fopen($GLOBALS["path"] . "full$postfix.csv", 'w');
	while (!feof($fvisits))
	{
		$visits_line = explode(';', fgets($fvisits));
		$visitors_line = explode(';', fgets($fvisitors));
		if (count($visits_line) == 3 && count($visitors_line) == 3)
		{
			// новая строка =     дата       ;        посетители       ;       посещения       ;       показы & \n
			$new_line = $visitors_line[0] . ';' . $visitors_line[1] . ';' . $visits_line[1] . ';' . $visitors_line[2];
			fputs($ffull, $new_line);
		}
	}
	fclose($fvisits);
	fclose($fvisitors);
	fclose($ffull);
}

Эту функцию надо поместить в stat.php (например в конец). Вызвать ее нужно 2 раза (отчет за все время и отчет за последние 3 месяца):

makeFull();
makeFull('_3');

Это нужно делать после генерации соответствующих отчетов, т.е. проще всего дописать в конце файла stat.php.

Далее из файлов visitors_3_settings.xml и visitors_settings.xml я сделал копии (full_3_settings.xml и full_settings.xml) и добавил в настройках графиков новый график-кривую (новую секцию <graph gid=»3″></graph>).

Осталось подредактировать index.php, чтобы новые графики отображались вместо старых. В index.php вместо кода первых четырех графиков появился следующий код:

	<div id="visitors" align="center" style="padding-bottom:80px">
<strong>Для просмотра сожержимого, установите последнюю версию Adobe Flash Player</strong>
</div>
<script type="text/javascript">
	// <![CDATA[
	var so = new SWFObject("amline.swf", "amline_chart", "600", "350", "8", "#FFFFFF");
	so.addVariable("path", "./amline/");
	so.addVariable("settings_file", escape("full_settings.xml?<?php echo mktime();?>"));
	so.addVariable("data_file", escape("full.csv?<?php echo mktime();?>"));
	so.addVariable("preloader_color", "#BBBBBB");
	so.write("visitors");
	// ]]>
</script>
<div id="visitors_3" align="center" style="padding-bottom:80px">
<strong>Для просмотра сожержимого, установите последнюю версию Adobe Flash Player</strong>
</div>
<script type="text/javascript">
	// <![CDATA[
	var so = new SWFObject("amline.swf", "amline_chart", "600", "400", "8", "#FFFFFF");
	so.addVariable("path", "./amline/");
	so.addVariable("settings_file", escape("full_3_settings.xml?<?php echo mktime();?>"));
	so.addVariable("data_file", escape("full_3.csv?<?php echo mktime();?>"));
	so.addVariable("preloader_color", "#BBBBBB");
	so.write("visitors_3");
	// ]]>
</script>

Вот и все. Теперь страница статистики (index.php) выглядит примерно так:

Вид сводных диаграм из Google.Analytics
Вид сводных диаграм из Google.Analytics

Скачка готовых файлов.

Мой мод вывода статистики затронул файлы из пакета statga от Andex’а. Изменения производились в версии statga 2.0.1. Не каснулись пакета только 2 новых файла: full_3_settings.xml и full_settings.xml. Их вы можете смело брать из моего пакета в любом случае. Как модернизировать файлы пакета statga для изменения визуализации написано выше. Так что, если Andex обновит версию, вы сможете внести правки вручную. Если нет, можно использовать готовые файлы версии 2.0.1:

Скачать модефицированную версию statga 2.0.1 feedbee mod.

]]>
https://valera.ws/2008.11.30~googleanalytics/feed/ 11
О жизни современного программиста https://valera.ws/2008.10.25~o-zhizni-sovremennogo-programmista/ https://valera.ws/2008.10.25~o-zhizni-sovremennogo-programmista/#respond Sat, 25 Oct 2008 10:52:00 +0000 http://valera.ws/?p=158 Читать далее О жизни современного программиста ]]> Реакция на комментарии на Хабре.

Да, питонисты — тихие спокойные ребята, а пхп-шники — агрессивные дурачки, потому что:

1) Питонисты и Рубироиды при каждом удобном случае лезут в топики про php и кричат, что php — гавно, а руби/питон — круто!

2) На форумах и в IRC-чатах, когда кто-то задает вопрос `как это сделать в php/java/с++/c#` тут же находятся рубироиды и питонщики, которые кричат, что это не надо делать на данном языке, а надо делать на руби или питоне! А автор вопроса — мудак!

3) Когда дается ответ на вопрос `как это сделать в php/java/с++/c#` в несколько строк кода, тут же находится довольный рубироид и пишет все в одну только ему понятную строчку и кричит `вот как все просто на руби, а вы мудаки все еще пишете на ХХХ`!

Как же это уже раздражает…

Ребята, если сидит компания из нескольких человек с пивом и обсуждает, как они хорошо съездили в Крым, не надо влазить в их беседу, объясняя, что Крым гавно, а Египет жжот. Есть большая вероятность, что вы получите в морду.

]]>
https://valera.ws/2008.10.25~o-zhizni-sovremennogo-programmista/feed/ 0
Профилирование PHP под Windows https://valera.ws/2008.10.22~php-profiling-under-windows/ https://valera.ws/2008.10.22~php-profiling-under-windows/#respond Wed, 22 Oct 2008 15:02:15 +0000 http://valera.ws/?p=151 Читать далее Профилирование PHP под Windows ]]> Рано или поздно все программисты PHP сталкиваются с необходимостью профилирования собственного кода. Она возникает на этапе оптимизации работы веб-приложения. Вообще, профилирование — это подсчет затрат времени на выполнение каждой отдельной функции (в том числе методов классов) в контексте времени генерации страницы-ответа целиком. О профилировании написано в Интернете достаточно много, поэтому на теории заострять внимание смысла нет. «Под катом» описана установка и настройка софта для профилирования PHP-скриптов в ОС Windows.

Для профилирования нам понадобится компонент подсчета времени выполнения функций PHP и формирования отчета и компонент визуального представления этого отчета для анализа.

Существуют как минимум 3 профайлера PHP-кода: Xdebug, Advanced PHP Debuger и DBG. Скажу честно, два последних я даже не рассматривал по двум причинам: Xdebug — самый популярный, Xdebug встроен в сборку xampp, которая стоит на моей локальной машине.

Установка Xdebug

Интеграция Xdebug’а в PHP очень проста. С сайта www.xdebug.org необходимо скачать DLL-extension для вашей версии PHP. Вот файл для PHP 5.2.1-5.2.6 под Windows. Скачанный файл необходимо положить в каталог расширений PHP (extension_dir). А в php.ini добавить следующие строки:

extension=php_xdebug.dll

[XDebug]
;; Only Zend OR (!) XDebug
zend_extension_ts=»c:\php\ext\php_xdebug.dll»
xdebug.remote_enable=true
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
xdebug.remote_handler=dbgp
xdebug.profiler_enable=1
xdebug.profiler_output_dir=»c:\temp»

При этом строки секции [Zend] требуется закомментировать (поставить ; в начале каждой строки):

[Zend]
;zend_extension_ts = «c:\php\zendOptimizer\lib\ZendExtensionManager.dll»
;zend_extension_manager.optimizer_ts = «c:\php\zendOptimizer\lib\Optimizer»
;zend_optimizer.enable_loader = 0
;zend_optimizer.optimization_level=15

Установите правильные пути в параметры zend_extension_ts и xdebug.profiler_output_dir секции XDebug. Путь xdebug.profiler_output_dir — это каталог, в который будет записан файл отчета.

На этом установка Xdebug закончена. Подробности по тонкой настройке этого расширения ищите при необходимости в гугле. Ознакомиться со всеми его возможностями можно на официальном сайте.

Установка KCachegrind под Windows

Открываем любую страницу вашего сайта и в каталоге xdebug.profiler_output_dir появляется файл отчета. Открывать его в Блокноте или другом средстве просмотра текстовых файлов нет никакого смысла. Его формат невозможно воспринять в текстовом виде. Для просмотра файла отчета понадобится средство KCachegrind, которое требует наличия KDE для запуска.

Есть, правда, еще WinCachegrind, но эта программулина глючная, слабенькая и с 2005 года не обновляется. Мой файл отчета она прочитать не смогла (parse error).

Итак, приступаем к установке KCachegrind под Windows. Благо, она абсолютно простая.

  1. Зайдите на www.winkde.org/pub/kde/ports/win32/installer/ и скачайте самую последнюю версию установщика.
  2. Запустите установщик (есть картинки процесса установки), выберите каталог установки (например в C:\KDE), скачайте то, что вам нужно (я выбрал все пакеты — это около 230 Мб).
  3. Добавьте переменную окружения KDEDIRS (Пуск > Панель управления > Система > Дополнительно > Переменные среды, нажмите «Создать» в разделе Пользовательские переменные и создайте переменную с именем KDEDIRS и значением равным папке, в которую Вы установили KDE4, напр. C:\KDE).
  4. Добавьте папку библиотек, %KDEDIRS%\lib, и папку исполняемых файлов, %KDEDIRS%\bin, к переменной %PATH% Windows. (Пуск > Панель управления > Система > Дополнительно > Переменные среды, дважды щелкните на системной переменной Path и добавьте эти строки, разделяя их точкой с запятой.)
  5. Если у Вас не установлена Visual Studio 2005 (или 2008), то скачайте и установите «Microsoft Visual C++ 2005 SP1 Redistributable Package (x86)«.
  6. Попробуйте запустить какое-нибудь Qt приложение в папке bin, например linguist.exe.
  7. Если получилось, попробуйте запустить любое приложение KDE, такое как kwrite.exe.

Дополнительная информация по установке.

На этом установка закончена. Вы можете запустить KCachegrind (c:\KDE\bin\kcachegrind.exe) и скормить ей файл вашего отчета профайлера.

Дополнительную информацию по профилированию PHP-кода можете почитать на сайте Zend’а, а я планирую написать еще статейку на эту тему, может даже завтра.

]]>
https://valera.ws/2008.10.22~php-profiling-under-windows/feed/ 0
Любые символы в именах переменных в PHP https://valera.ws/2008.10.21~lyubye-simvoly-v-imenax-peremennyx-v-php/ https://valera.ws/2008.10.21~lyubye-simvoly-v-imenax-peremennyx-v-php/#respond Tue, 21 Oct 2008 10:33:38 +0000 http://valera.ws/?p=148 Хотите использовать в именах переменных PHP любые символы?

Следующий пример абсолютно работоспособен:

<?php

$name = ‘что угодно — 1 + 44.4’;

$$name  = ‘ДА!’;

echo $$name;

]]>
https://valera.ws/2008.10.21~lyubye-simvoly-v-imenax-peremennyx-v-php/feed/ 0
Smarty 3 https://valera.ws/2008.10.21~smarty-3/ https://valera.ws/2008.10.21~smarty-3/#respond Tue, 21 Oct 2008 07:17:58 +0000 http://valera.ws/?p=144 Читать далее Smarty 3 ]]>

Оказывается, шаблонизатор для PHP-сайтов Smarty еще жив! 17 октября на сайте появилась новость о том, что доступен альфа-релиз 3-й версии со значительными изменениями, который не совместим с версией 2.

Так как самомуписать обзор изменений лень, приведу выжимку из обсуждения темы на habrahabr’e.

Интерфейс шаблонизатора особо не изменился. Это всё те же display(), fetch() и assign(), которые покрывают процентов 99 всех потребностей. Исчез метод assign_by_ref().

Внутренности же претерпели более существенные изменения:

  • Отказ от поддержки PHP4 и полное использование объектно-ориентированных возможностей PHP5. То есть в шаблонах можно использовать разыменования объектов без костылей;
  • Объектно-ориентированный подход затронул и плагины: теперь каждый плагин является классом, отнаследованным от Smarty_Internal_PluginBase
  • Файл основного класса — Smarty.class.php — стал подозрительно маленьким: всего 11 кб, включая здоровенные спойлеры лицензии LGPL ;)
  • Все требуемые элементы, исключённые из ядра, подгружаются лишь по мере необходимости (lazy loading)
  • Маленькая приятность — встроенная реализация паттерна singleton.
  • Поддержка нативных PHP-шаблонов.

Надо сказать, что по сравению с веткой 2.x, дистрибутив значительно потолстел: папка libs, экспортированная из SVN, заняла немногим менее 800 кб, в то время как в версии 2.6.20 её вес был был порядка 320 кб.

Подробности о релизе — в официальном README.

Желающие могут вытащить версию из SVN:
svn checkout smarty-php.googlecode.com/svn/branches/Smarty3Alpha/

Вот тут groups.google.com/group/smarty-developers/browse_thread/thread/c29ae569842882cd немного про синтаксис:

PHP: <?= $foo ?>
Smarty: {$foo} // same as Smarty 2

PHP: <?= $foo[‘bar’] ?>
Smarty: {$foo[‘bar’]} // no more {$foo.bar}

PHP: <?= $foo[$bar][$foo[‘bar’]] ?>
Smarty: {$foo[$bar][$foo[‘bar’]] ?> // identical to PHP

PHP: <?php foreach($foo as $bar) {… } ?>
Smarty: {foreach $foo as $bar}… {/foreach} // just a delimiter
adjustment

PHP: <?php for($x = 0; $x<$y; $x++) {… } ?>
Smarty: {for $x=0; $x<$y; $x++}… {/for} // get rid of {section}

PHP: <?php if($foo == $bar && $blah !== ‘ziggy’) {… } ?>
Smarty: {if $foo == $bar && $blah !== ‘ziggy’}… {/if}

]]>
https://valera.ws/2008.10.21~smarty-3/feed/ 0
Zend Framework — это круто! https://valera.ws/2008.10.16~zend-framework-eto-kruto/ https://valera.ws/2008.10.16~zend-framework-eto-kruto/#respond Thu, 16 Oct 2008 11:12:55 +0000 http://valera.ws/?p=134 Читать далее Zend Framework — это круто! ]]>

Zend Framework — это круто. Круто, потому что удобно и логично. Потому что в нем нет ничего лишнего: можно использовать как весь фреймворк целиком, так и отдельные его компоненты. Все компоненты можно заменить своими, не нарушая целостности фреймворка. Зенд не представляет готовые части сайта, и тем более — сайты. Zend Framework — это помощник в создании сайта, не более того. Очень гибкий, масштабируемый.

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

В то же время я понимал, что функционал моего фреймворка в разы уступает функционалу и качеству фреймворков, которые написаны профессиональными командами или большим сообществом программистов. Глупо считать, что они человек может написать достойного конкурента таким монстрам, как ZF, CakePHP, symfony. Понимая это, я просто ждал момента, когда сделают достойный перехода на него фреймворк. И вот, похоже, дождался.

Изучать ZF начал с версии 1.6. Почитал Quick Start, затем начал читать мануал. Обратил внимание, что большинство идей ZF сходятся с теми идеями, на которых я строил свой движок, причем автономно, не изучая особенности других фреймворков. Только вот реализация этих идей, естественно, у ZF гораздо лучше, полнее. Факт схожести идей заложил в моем сознании доверие к этому фреймворку. Кроме того, слышал хорошие отзывы о нем от других программистов, которые использовали раньше и используют сейчас разные фреймворки и имеют достойный опыт сравнения.

Может быть эта запись в блоге подвигла вас на изучение ZF? Тогда расскажу вам вот что. Прежде всего, сходите на сайт Zend Framework‘а и оглядитесь вокруг :) Изучение начинайте с Quick Start‘а. Там все довольно хорошо описано, но с большего. Т.е. вы сможете подготовиться к восприятию тонкостей и деталей подробного мануала. Соберите на вашем сервере сайт, который предлагает Quick Start, поэкспериментируйте с ним. Только после этого переходите к полному руководству программиста.

Так как руководство состоит из описания отдельных компонентов фреймворка (52 главы-компонента на данный момент), нужно определиться, с чего начать. Поможет опредлитсья вам как раз Quick Start. Я приведу свой порядок изучения: Introduction, Zend_Controller, Zend_Cache, Zend_Loader, Zend_View, Zend_Layout, Zend_Config, Zend_Db. Дальнейший порядок, в принципе, значения не имеет.

]]>
https://valera.ws/2008.10.16~zend-framework-eto-kruto/feed/ 0