Начало выделения: Alt-A или Ctrl-^
Навигация до момента выполнения действия над текстом
Удаление текста: Ctrl-K или F9
Копирование в буфер: Alt-6
Вставка текста из буфера: Ctrl-U или F10
Ярлыки
.htaccess
(4)
тестирование
(8)
шаблоны проектирования
(3)
css
(5)
Debian
(6)
docker
(2)
Doctrine2
(6)
Git
(6)
html
(4)
java
(6)
javascript
(13)
jquery
(11)
LFS
(3)
linux
(23)
mac os
(4)
mod_rewrite
(2)
MSSQL
(4)
MySQL
(18)
ORM Doctrine
(17)
patterns
(3)
PDO
(3)
perl
(7)
PHP
(64)
PHPUnit
(8)
Python
(15)
SEO
(2)
Silex
(1)
SimpleXML
(1)
SQL
(14)
ssh
(4)
Ubuntu
(24)
Yii1
(1)
Zend Framework
(19)
ZendFramework2
(8)
вторник, 28 февраля 2012 г.
суббота, 25 февраля 2012 г.
Zend Framework. Декоратор формы Description.
Например, данные пользователя не приняты на сервере, удобно послать сообщение методом setDescription.
Чтобы это работало надо установить декоратор для формы:
Чтобы это работало надо установить декоратор для формы:
class LoginForm extends Zend_Form { public function init() { ... $this->setDecorators(array('Description', 'FormElements', 'Form')); ... } }После этого можно использовать:
$form = new LoginForm(); $form->setDescription('Неправильные имя или пароль'); $form->populate($formData)
пятница, 24 февраля 2012 г.
Git. Основы.
Работаем в одиночку
В каталоге проекта выполняем создаем репозиторий
git initДобавляем файлы проекта
git add .Делаем коммит (всегда предварительно надо добавлять отредактированные файлы)
git commit -m "First Commit"Потребовался новый функционал - создаем ветку
git branch new-featureПереключаемся на нее
git checkout new-featureВносим изменения и смотрим на них, индексируем, делаем коммит
git status git add . git commit -m "New feature added"Делаем слияние веток, переключаемся на master
git checkout master git merge new-featureЕсли требуется внести небольшое изменение, можно не создавать ветку:
git stashВносим изменения и применяем их
git stash apply
Работа с удаленным репозиторием
Копируем репозиторий
git clone git://github.com/username/project.git masterКоманда создала у вас репозитарий, и внесла туда копию ветки master проекта project.
Создаем новую ветку, вносим изменения в код
git branch new-feature edit README git add .git
commit -m "Added a super feature"Переходим в основную ветку, заберем последние изменения в проекте, и попробуем добавить новую фишку в проект:
git checkout master git pull git merge new-featureЕсли есть конфликты - решаем, если нет, то сразу выгружаем
git push
Как сделать push в серверный репозиторий с файлами.
git config receive.denyCurrentBranch ignoreТакже пишем в .git/hooks/post-receive
#!/bin/bash cd .. env -u GIT_DIR git reset --hard masterПомечаем как исполняемый
chmod a+x .git/hooks/post-receive
Копирование ветки удаленного репозитория
git checkout -b experimental origin/experimental
Создание пустой ветки без коммитов
git checkout --orphan mybranch
вторник, 21 февраля 2012 г.
Ubuntu. Установка пакета i386 на amd64.
Захотелось поставить антивирус avast! Linux Home Edition
На сайте сборка для i386, иногда можно установить с помощью ключа --force-architecture
leon@Berta:~/Рабочий стол$ sudo dpkg -i --force-architecture avast4workstation_1.3.0-2_i386.deb [sudo] password for leon: Выбор ранее не выбранного пакета avast4workstation:i386. (Чтение базы данных ... на данный момент установлено 331920 файлов и каталогов.) Распаковывается пакет avast4workstation:i386 (из файла avast4workstation_1.3.0-2_i386.deb)... Настраивается пакет avast4workstation:i386 (1.3.0) ... Обрабатываются триггеры для man-db ...В данном случае работает
четверг, 16 февраля 2012 г.
Doctrine2. Введение.
Doctrine2 - object-relational mapper (ORM) для PHP 5.3.0+
Ядром является реализация шаблона Data Mapper
- они не могут быть final или иметь методы final;
- реализовывать clone или wakeup;
... Entity имеет свойства сохраняемые в базе данных и получаемые из нее.
Что такое Entities?
Entities (классы модели) - объекты PHP, которым не надо расширять или реализовывать никакие абстрактные классы или интерфейсы. Есть некоторые ограничения, например,
- они не могут быть final или иметь методы final;
- реализовывать clone или wakeup;
... Entity имеет свойства сохраняемые в базе данных и получаемые из нее.
Пример модели: BUG TRACKER
Требования: Ошибка имеет описание, дату создания, статус, корреспондента и разработчика Ошибка может происходить с разными продуктами (платформами) Продукт имеет название Корреспондент и разработчик - оба пользователи системы Пользователь может сообщить об ошибке Назначенный разработчик должен исправить ошибку Пользователь может видеть все ошибки о которых он сообщил или для решения которых он назначен Ошибки могут быть представлены как список с постраничным выводом
Создание проекта
Установите Doctrine2
$ pear channel-discover pear.doctrine-project.org $ pear install --alldeps doctrine/DoctrineORMСоздайте каталог проекта
$ mkdir project $ cd projectСтруктура должна быть такой
project |-- config | |-- xml | `-- yaml `-- entities
Начало проектирования модели
Создайте классы
// Bug.php class Bug { protected $id; protected $description; protected $created; protected $status; } // Product.php class Product { protected $id; protected $name; public function getId() { return $this->id; } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } } // User.php class User { protected $id; public $name; // public for educational purpose, see below public function getId() { return $this->id; } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } }Создание связей
// entities/Bug.php use Doctrine\Common\Collections\ArrayCollection; class Bug { // ... (previous code) protected $products = null; public function __construct() { $this->products = new ArrayCollection(); } } // entities/User.php use Doctrine\Common\Collections\ArrayCollection; class User { // ... (previous code) protected $reportedBugs = null; protected $assignedBugs = null; public function __construct() { $this->reportedBugs = new ArrayCollection(); $this->assignedBugs = new ArrayCollection(); } }Для отладки классов не используйте var_dump() и тд, используйте Doctrine\Common\Util\Debug::dump() Создаем связи между пользователем и ошибкой
// entities/Bug.php class Bug { // ... (previous code) protected $engineer; protected $reporter; public function setEngineer($engineer) { $engineer->assignedToBug($this); $this->engineer = $engineer; } public function setReporter($reporter) { $reporter->addReportedBug($this); $this->reporter = $reporter; } public function getEngineer() { return $this->engineer; } public function getReporter() { return $this->reporter; } } // entities/User.php class User { // ... (previous code) protected $reportedBugs = null; protected $assignedBugs = null; // Используется именование методов в прошедшем времени, // это обозначает что назначение уже произошло и // и методы используются лишь для обеспечения согласованности ссылки. // Очевидно что одностороннее использование методов // User::addReportedBug() и User::assignedToBug() // в пользовательском коде не добавит ошибку в коллекцию // в свойствах Bug::$reporter или Bug::$engineer. // Использование этих методов и вызов Doctrine не обновят // представление коллекций в базе данных. public function addReportedBug($bug) { $this->reportedBugs[] = $bug; } public function assignedToBug($bug) { $this->assignedBugs[] = $bug; } }
Метаданные отображения для классов модели
Далее надо добавить метаданные для Doctrine, чтобы классы модели могли быть сохранены в базе данных. Это можно сделать 3 способами: XML, YAML, аннотации. В первом и втором случае, мы создаем файлы и кладем их в каталоги project/config/xml и project/config/yaml соотвественно. В последнем - аннотации добавляются непосредственно в код класса. Пример для продукта
// entities/Product.php /** * @Entity @Table(name="products") **/ class Product { /** @Id @Column(type="integer") @GeneratedValue **/ protected $id; /** @Column(type="string") **/ protected $name; // .. (other code) } <!-- config/xml/Product.dcm.xml --> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="Product" table="products"> <id name="id" type="integer"> <generator strategy="AUTO" /> </id> <field name="name" type="string" /> </entity> </doctrine-mapping> # config/yaml/Product.dcm.yml Product: type: entity table: products id: id: type: integer generator: strategy: AUTO fields: name: type: stringДля поля id дерективы указывают на то, что будет использован механизм генерации родной для СУБД (AUTO INCREMENT для MySQL, например). Для Bug
// entities/Bug.php /** * @Entity @Table(name="bugs") **/ class Bug { /** * @Id @Column(type="integer") @GeneratedValue **/ protected $id; /** * @Column(type="string") **/ protected $description; /** * @Column(type="datetime") **/ protected $created; /** * @Column(type="string") **/ protected $status; /** * @ManyToOne(targetEntity="User", inversedBy="assignedBugs") **/ protected $engineer; /** * @ManyToOne(targetEntity="User", inversedBy="reportedBugs") **/ protected $reporter; /** * @ManyToMany(targetEntity="Product") **/ protected $products; // ... (other code) } <!-- config/xml/Bug.dcm.xml --> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="Bug" table="bugs"> <id name="id" type="integer"> <generator strategy="AUTO" /> </id> <field name="description" type="text" /> <field name="created" type="datetime" /> <field name="status" type="string" /> <many-to-one target-entity="User" field="reporter" inversed-by="reportedBugs" /> <many-to-one target-entity="User" field="engineer" inversed-by="assignedBugs" /> <many-to-many target-entity="Product" field="products" /> </entity> </doctrine-mapping> # config/yaml/Bug.dcm.yml Bug: type: entity table: bugs id: id: type: integer generator: strategy: AUTO fields: description: type: text created: type: datetime status: type: string manyToOne: reporter: targetEntity: User inversedBy: reportedBugs engineer: targetEntity: User inversedBy: assignedBugs manyToMany: products: targetEntity: ProductТут определны две ссылки на сущность User. Имя класса связанной сущности задается тэгом targetEntity. Имеет место двунаправленная связь, поэтому с помощью тэга inversedBy указываем атрибут связанной сущности, соответствующей нашему объекту. И наконец для User
// entities/User.php /** * @Entity @Table(name="users") **/ class User { /** * @Id @GeneratedValue @Column(type="integer") * @var int **/ protected $id; /** * @Column(type="string") * @var string **/ protected $name; /** * @OneToMany(targetEntity="Bug", mappedBy="reporter") * @var Bug[] **/ protected $reportedBugs = null; /** * @OneToMany(targetEntity="Bug", mappedBy="engineer") * @var Bug[] **/ protected $assignedBugs = null; // .. (other code) } <!-- config/xml/User.dcm.xml --> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="User" table="users"> <id name="id" type="integer"> <generator strategy="AUTO" /> </id> <field name="name" type="string" /> <one-to-many target-entity="Bug" field="reportedBugs" mapped-by="reporter" /> <one-to-many target-entity="Bug" field="assignedBugs" mapped-by="engineer" /> </entity> </doctrine-mapping> # config/xml/User.dcm.yml User: type: entity table: users id: id: type: integer generator: strategy: AUTO fields: name: type: string oneToMany: reportedBugs: targetEntity: Bug mappedBy: reporter assignedBugs: targetEntity: Bug mappedBy: engineerСвязи один-ко-многим уже определены на стороне владельца (Bug), поэтому поэтому просто указываем его атрибут с помощью тэга mappedBy.
Настройка EntityManager
Выборку и сохранение сущностей в базе данных обеспечивает EntityManager. Для этого его необходимо создать и настроить.
// bootstrap_doctrine.php // See :doc:`Configuration <../reference/configuration>` for up to date autoloading details. use Doctrine\ORM\Tools\Setup; require_once "Doctrine/ORM/Tools/Setup.php"; Setup::registerAutoloadPEAR(); // Create a simple "default" Doctrine ORM configuration for XML Mapping $isDevMode = true; $config = Setup::createXMLMetadataConfiguration(array(__DIR__."/config/xml"), $isDevMode); // or if you prefer yaml or annotations //$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/entities"), $isDevMode); //$config = Setup::createYAMLMetadataConfiguration(array(__DIR__."/config/yaml"), $isDevMode); // database configuration parameters $conn = array( 'driver' => 'pdo_sqlite', 'path' => __DIR__ . '/db.sqlite', ); // obtaining the entity manager $entityManager = \Doctrine\ORM\EntityManager::create($conn, $config);Продолжение следует (или нет) ...
среда, 8 февраля 2012 г.
Debian. Обновление php на debian 5 lenny.
На данный момент доступна версия 5.3.10
Добавляем реп в /etc/apt/sources.list
Качаем и ставим ключ
Обновляем
Добавляем реп в /etc/apt/sources.list
deb http://php53.dotdeb.org oldstable all deb-src http://php53.dotdeb.org oldstable all
Качаем и ставим ключ
wget http://www.dotdeb.org/dotdeb.gpg cat dotdeb.gpg | sudo apt-key add -
Обновляем
apt-get update apt-get dist-upgrade
вторник, 7 февраля 2012 г.
Zend Framework. Создание rss или atom потока.
Форматируем данные
Импорт в поток
Вывод
//Create an array for our feed $feed = array(); //Setup some info about our feed $feed['title'] = "ZendCoding.com's Newest Stories"; $feed['link'] = 'http://www.zendcoding.com/newest-stories.rss'; $feed['charset'] = 'utf-8'; $feed['language'] = 'en-us'; $feed['published'] = time(); $feed['entries'] = array();//Holds the actual items //Loop through the stories, adding them to the entries array foreach($stories->fetchAll($select) as $story){ $entry = array(); //Container for the entry before we add it on $entry['title'] = $story->title; //The title that will be displayed for the entry $entry['link'] = $story->url; //The url of the entry $entry['description'] = $story->teaser; //Short description of the entry $entry['content'] = $story->description; //Long description of the entry //Some optional entries, usually the more info you can provide, the better $entry['lastUpdate'] = $story->modified; //Unix timestamp of the last modified date $entry['comments'] = $story->commentsUrl; //Url to the comments page of the entry $entry['commentsRss'] = $story->commentsRssUrl; //Url of the comments pages rss feed $feed['entries'][] = $entry; }
Импорт в поток
$feedObj = Zend_Feed::importArray($feed, 'rss'); //Or importArray($feed, 'atom');
Вывод
//Return the feed as a string, we're not ready to output yet $feedString = $feedObj->saveXML(); //Or we can output the whole thing, headers and all, with $feedObj->send();
четверг, 2 февраля 2012 г.
Git. Установка и настройка репозитория для веб-сайта.
Установка git на debian, ubuntu:
Если хотим, чтобы каталоги или файлы были исключены из репозитория, надо создать файл .gitignore в каталоге сайта:
Создаем репозиторий на локальной машине. Для этого заходим в каталог сайта:
Доступ будет по ssh. На сервере в корне сайта создаем каталог и пустой репозиторий:
Далее на сервере указываем действие, которое будет совершаться после коммита. Для этого в скрипт post-recieve добавляем переменную, которая указывает на каталог, в который будут распаковываться файлы. Ставим права на исполнение:
На локальной машине выгружаем репозиторий на сервер:
$ sudo apt-get install git-core
Если хотим, чтобы каталоги или файлы были исключены из репозитория, надо создать файл .gitignore в каталоге сайта:
$ touch .gitignore $ cat .gitignore >> images/ $ cat .gitignore >> robots.txt
Создаем репозиторий на локальной машине. Для этого заходим в каталог сайта:
$ git init Initialized empty Git repository in /var/www/mysite $ git commit -a -m "my first commit"
Доступ будет по ssh. На сервере в корне сайта создаем каталог и пустой репозиторий:
$ mkdir mysite.git && cd mysite.git $ git init --bare Initialized empty Git repository in /var/www/mysite/mysite.git/
Далее на сервере указываем действие, которое будет совершаться после коммита. Для этого в скрипт post-recieve добавляем переменную, которая указывает на каталог, в который будут распаковываться файлы. Ставим права на исполнение:
$ cat > hooks/post-receive #!/bin/sh GIT_WORK_TREE=/var/www/mysite git checkout -f $ chmod +x hooks/post-receive
На локальной машине выгружаем репозиторий на сервер:
$ git remote add origin user@mysite:/var/www/mysite/mysite.git $ git push origin master user@mysite's password: Counting objects: 6735, done. Delta compression using up to 4 threads. Compressing objects: 100% (6512/6512), done. Writing objects: 100% (6735/6735), 22.22 MiB | 191 KiB/s, done. Total 6735 (delta 2614), reused 0 (delta 0) To user@mysite:/var/www/mysite * [new branch] master -> master
Подписаться на:
Сообщения (Atom)