Показаны сообщения с ярлыком PHP. Показать все сообщения
Показаны сообщения с ярлыком PHP. Показать все сообщения

вторник, 11 августа 2009 г.

Следование стандартам...

Так сложилось, что вот уже несколько месяцев занимаюсь программированием на PHP, пишу свои классы и модули, попутно ковыряя чужие, верстаю и т.д. и т.п. И за всё это время я не видил НИ ОДНОГО продукта (естественно опенсорс) полностью соответствующего стандартам W3C и парадигмам ООП. Интересно, почему разработчики столь наплевательски относятся к стандартам, по сути писавшимся для них, дабы облегчить их нелёгкий труд?

С ООП всё, более или менее, понятно. PHP изначально был процедурным языком и ни о каком ООП в нём речи не шло. Да и сейчас в версии 5.1 часть парадигм ООП не полностью поддерживается или поддерживается с помощью всевозможных "костылей" выдаваемых за преимущества PHP.
Например в PHP нет т.н. акцессоров и мутаторов, точнее они "как бы" есть, предлагается пользоваться следующей конструкцией:
<?php
class MyClass {
private $properties;
function __set($name, $value) {
echo "задание нового свойства $name = $value";
$this->properties[$name]=$value;
}
function __get($name) {
echo "чтение значения свойства ", $name;
return $this->properties[$name];
}
}
$obj = new MyClass;
$obj->property = 1; // Выводит "задание нового свойства property=1"
$a = $obj->property; // Выводит "чтение значения свойства property"
echo $a; // выводит 1;
?>

Таким методом конечно можно обрабатывать изменения свойств объектов, но для того чтобы заставить класс принимать только нужные (запланированные) параметры придётся писать switch и в нём проверять имена указываемых пользователем параметров, что не слишком то удобно.

А вот со стандартами косорциума W3C всё не так просто. По какой то не ведомой мне причине практически все разработчики плюют на эти стандарты и воротят ТАКОЕ, что хватаешься за голову.
Вроде бы HTML все в школе/техникуме/институте изучают, да и W3C на месте не сидит, создавая для разработчиков всякие валидаторы, обнаруживающие ошибки в гипертексте странички и подробно разбирая каждую в соответствии со стандартом. В инете полно русско-язычных (и не только русско) ресурсов с подробным объяснением всех этих стандартов. И тем не менее разработчики продолжают испытывать браузеры на прочность своим бредом в гипертексте и жабаскрипте. Просто ради интереса зайдите вот сюда -> http://validator.w3.org/check?uri=http%3A%2F%2Fwww.lastfm.ru%2F&charset=%28detect+automatically%29&doctype=Inline&group=0&user-agent=W3C_Validator%2F1.654 и обалдейте от количества ошибок и варнингов найденных валидатором в коде странички (страничка подвернулась случайно, просто этот сайт упорно отказывается у меня работать под оперой уже в течении двух его версий).
А вот и тест любимого ВКонтакта -> http://validator.w3.org/check?uri=http%3A%2F%2Fvkontakte.ru&charset=%28detect+automatically%29&doctype=Inline&group=0
Причём заметьте, и тот и другой -- являются коммерческими проектами. Про не коммерческий код я вообще молчу...

SEF Service Map & UTF-8 encoded URLs

SEF Service Map это компонент, перед которым стоит задача создания полной карты сайта.
Кроме того компонент совместим со всеми стандартными расширениями Joomla! (статьи, RSS ленты, ссылки, контакты и т.д.),
SEF Service Map является открытым компонентом - это позволяет интегрировать его с другими компонентами,
такими как галереи, форумы, каталоги и другие, благодаря встроенным механизмам интеграции!

SEF Service Map создает не только карту сайта, но и карту совместимую со стандартом sitemaps.org :
- XML карта (например: для Google)
- TXT карта (например: для Yahoo)

Но эта зараза на отрез отказывается работать совместно с русскоязычными UTF-8 урликами вида: http://some.site/Новости/Новости-сайта/Превеееед-медвед.html
Точнее работать то она с ними работает и даже HTML-карту генерирует валидную, а вот с XML- и TXT- картами проблема. Все красивые русские урлики в них выглядят примерно так: http://some.site/Ð�овоÑ�ти/Ð�овоÑ�ти-Ñ�айта/

Порывшись в коде нашёл проблему. Разработчики при генерации XML- и TXT- карт выполняют перекодировку линка на статью в UTF-8. Вобщем проблема решается таким образом:
  1. Открываем файлик /components/com_sefservicemap/sefservicemap.html.php
  2. Закомменчиваем или удаляем все вхождения строки "$link = utf8_encode($link);" (их 2)
  3. Радуемся жизни... ;)

среда, 29 июля 2009 г.

"Продвинутый" пример использования PHPLinq

Музыка: Hospital Mix.Six (Mixed By Cyantific)

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

Представим, что есть у нас пять яблок массив объектов Employee (служащий). А нужно нам отсортировать этот массив по имени и возрасту служащих и получить в результате массив только тех служащих, имя которых состоит из четырёх символов. И чтобы уж совсем усложнить задачу, в результате мы хотим получить не массив экземпляров класса Employee, а массив объектов, содержащих мыло и домен почтового сервера служащего. Жестоко, не правдали? ;)
Перво на перво, объявим класс служащих и заполним массив экземплярами этого класса:

class Employee {
public $Name;
public $Email;
public $Age;

public function __construct($name, $email, $age) {
$this->Name = $name;
$this->Email = $email;
$this->Age = $age;
}
}

$employees = array(
new Employee('Maarten', 'maarten@example.com', 24),
new Employee('Paul', 'paul@example.com', 30),
new Employee('Bill', 'bill.a@example.com', 29),
new Employee('Bill', 'bill.g@example.com', 28),
new Employee('Xavier', 'xavier@example.com', 40)
);

А теперь легко и не принуждённо с помощью PHPLinq брюки превращаются... превращаются... выполним, поставленную в начале, задачу:

$result = from('$employee')->in($employees)
->where('$employee => strlen($employee->Name) == 4')
->orderBy('$employee => $employee->Name')
->thenByDescending('$employee => $employee->Age')
->select('new {
"EmailAddress" => $employee->Email,
"Domain" => substr($employee->Email, strpos($employee->Email, "@") + 1)
}');

И снова, как и в предыдущем примере, вы могли заметить странный код 'new { }'. Что он делает? А он конвертируется в объект анонимного типа (класса). Например, конструкция вида new { "name" => "test" } преобразуется в объект содержащий поле "name" со значением "test".

понедельник, 20 июля 2009 г.

PHPLinq: Language Integrated Query for PHP

PHPLinq -- это набор классов PHP имитирующий функциональность предоставляемую расширением LINQ языка C#. LINQ позволят обращаться к данным из программы, способом очень сильно напоминающим SQL, но минуя написание SQL запросов как таковых.
Например, пусть у нас есть массив строк и мы хотим выбрать из него только те строки, длина которых меньше пяти символов. Обычным способом нам потребовалось бы писать цикл, в котором мы бы проверяли длину каждого элемента массива и добавляли бы подходящие по длине элементы во временную переменную:
// Создаём массив строк
$Names = array("John", "Peter", "Joe", "Patrick", "Donald", "Eric");
$Result = array();
foreach ($Name in $Names) {
if (strlen($Name) < 5) {
$Result[] = $Name;
}
}
С помощью PHPLinq это легко сделать следующим способом:
// Создаём массив строк
$Names = array("John", "Peter", "Joe", "Patrick", "Donald", "Eric");
$Result = from('$Name')->in($Names)
->where('$Name => strlen($Name) < 5')
->select('$Name');
Похоже на SQL? ;) Кроме того, решение с использованием PHPLinq гораздо компактнее и выглядит гораздо более красиво. Сам автор PHPLinq, Maarten Balliauw, пишет:
С LINQ есть одна проблемка... Если вы начали использовать его, то вы не захотите больше обращаться к источникам данных иными способами.
P.S.: В четвёртой строчке второго листинга вы могли заметить странную конструкцию '$Name => strlen($Name) < 5. Эта конструкция преобразуется в анонимную функцию или другими словами лямбда-выражение. Эта функция принимает параметр $Name и возвращает булево значение которое является результатом вычисления выражения strlen($Name) < 5.

Домашняя страничка PHPLinq -> http://www.phplinq.net/

среда, 8 апреля 2009 г.

Классы, их наследование и объекты "на пальцах"

Часто приходится объяснять студентам "на пальцах", что такое "классы", "объекты" и что значит это "наследование" в ООП. И вот недавно, объясняя эти вещи студентам в очередной раз, написал небольшой "жизненный" пример призванный облегчить переход мозга юного специалиста к объектно-ориентированному мышлению.

Итак, что же такое классы и их наследники и чем они отличаются от объектов.

Возьмём, к примеру, класс Стол. Этот класс обладает свойствами: Длина, Ширина, Высота. И имеет метод, например: Стоять.
У класса Стол есть наследники (дочерние классы). Например, класс ПисьменныйСтол и КомпьютерныйСтол. Эти классы наследуют от родительского класса Стол все его свойства (Длина, Ширина, Высота) и методы (Стоять), но класс ПисьменныйСтол, по мимо унаследованных от родительского класса Стол свойств и методов, может иметь дополнительное своство КоличествоЯщиков и метод ВыдвинутьЯщик. Также и класс КомпьютерныйСтол может иметь свойство КоличествоСекцийДляCD и метод ВыдвинутьСтолешницу.
Стол
, КомпьютерныйСтол и ПисьменныйСтол -- это классы.
Почему?
Потому что это некоторые сущности, которые описывают некий набор свойств и поведений характерных для всех столов (класс Стол) или только для компьютерных столов (класс КомпьютерныйСтол) или только для письменных столов (класс ПисьменныйСтол).
Но тогда что же такое объект?
Объект -- это стол за которым ты сейчас сидишь (причём скорее всего это объект класса КомпьютерныйСтол). Объект -- это (в большинстве случаев) экземпляр некоторого класса. Также как твой компьютерный стол является экземпляром класса КомпьютерныйСтол.

Перенося всё это в PHP код получим:

<?php

/**
* Стол
*/
class Table {
/**
* Длина стола
* @var float
*/
public Length;

/**
* Ширина стола
* @var float
*/
public Width;

/**
* Высота стола
* @var float
*/
public Height;

/**
* Осуществляет стояние стола
*/
public function Stand() {

}
}

/**
* КомпьютерныйСтол
*/
class ComputerTable extends Table {
/**
* Количество секций для CD
* @var int
*/
public CDSectionsCount;

/**
* Выдвигает столешницу с клавиатурой
*/
public function MoveOutTabletop() {

}
}

/**
* ПисьменныйСтол
*/
class Desk extends Table {
/**
* Количество ящиков
* @var int
*/
public DeskDrawerCount

/**
* Выдвигает ящик с указанным номером
* @param int $DeskDrawerNumber Номер выдвигаемого ящика
*/
public function MoveOutDeskDrawer($DeskDrawerNumber) {

}
}

$MyTable = new Table(); // а вот $MyTable -- это уже объект класса Table
$MyTable->Width = 1;
$MyTable->Height = 0.7;
$MyTable->Length = 3;

$MyComputerTable = new ComputerTable(); // $MyComputerTable -- тоже объект
$MyComputerTable->Width = 0.8; // и так как класс ComputerTable является
$MyComputerTable->Height = 0.7; // наследником класса Table, то он имеет
$MyComputerTable->Length = 0.5; // все теже свойства что и объект $MyTable
$MyComputerTable->CDSectionsCount = 5; // плюс новое свойство CDSectionsCount

$MyComputerTable->Stand(); // Аналогично свойствам наследуются и методы
$MyComputerTable->MoveOutTabletop();

?>


P.S.: PHP -- не лучший выбор для начала освоениея ООП, но сейчас я пишу в основном на нём.

вторник, 17 марта 2009 г.

JPATH_ROOT, JPATH_BASE и JPATH_SITE в чём разница?

Итак, в чём же разница меж этими константами в Joomla? Этим вопросом я задавался достаточно длительное время, но на поиски различий времени никогда не было, хотя эти самые различия несомненно должны были быть! =)
Сегодня наконец-то руки дошли погуглить по данному сабжу. И вот результат:

JPATH_ROOT -- всегда содержит путь установки (куда на web-сервере была установлена) Joomla!, только его и ничто другое.
JPATH_SITE -- всегда содержит путь к приложению (экземпляру класса JApplication) JSite, то есть путь где находится корень front-end'а Joomla. Аналогично JPATH_ADMINISTRATOR -- содержит путь к корню back-end'а Joomla.
JPATH_BASE -- всегда содержит путь к корню текущего приложения, то есть когда вы находитесь в back-end константа JPATH_BASE == JPATH_ADMINISTRATOR, а когда находитесь во front-end -- JPATH_BASE == JPATH_SITE.

Вот такие вот они константы в Joomla...