Ярлыки

.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)

четверг, 30 сентября 2010 г.

SQL. MySQL. Удаление внешнего ключа.

InnoDB позволяет добавить ограничение внешнего ключа с помощью ALTER TABLE:
ALTER TABLE tbl_name
    ADD [CONSTRAINT [symbol]] FOREIGN KEY
    [index_name] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name,...)
    [ON DELETE reference_option]
    [ON UPDATE reference_option]
InnoDB поддерживает использование ALTER TABLE для удаления внешнего ключа:
ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol;
Пример:
--
-- Ограничения внешнего ключа таблицы `playlist`
--
ALTER TABLE `playlist` ADD CONSTRAINT `playlist_user_id_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

ALTER TABLE `playlist` DROP FOREIGN KEY `playlist_user_id_user_id`

среда, 29 сентября 2010 г.

Jquery. Передача дополнительных параметров неанонимному обработчику события.


function handler(event) {
alert(event.data.foo);
}
$("p").bind("click", {foo: "bar"}, handler)


Как результат получаем 'bar'.

C++. STL. Map.


#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <map>
using namespace std;

main () {
map<int, string> myMap1;
myMap1[1] = "leon bob";
myMap1[2] = "john doe";
myMap1[3] = "jane doe";
map<int, string>::iterator i;
for(i=myMap1.begin(); i!=myMap1.end(); i++) {
cout << (*i).first << ":" << (*i).second << endl;
}
cout << myMap1[1] << endl;
map<string, string> myMap2;
myMap2["leonBob"] = "developer";
cout << myMap2["leonBob"] << endl;
}


leon@leon-desktop:~/cpp$ g++ myapp.cpp
leon@leon-desktop:~/cpp$ ./a.out
1:leon bob
2:john doe
3:jane doe
leon bob
developer

понедельник, 27 сентября 2010 г.

среда, 22 сентября 2010 г.

ORM Doctrine. Реальное наследование (concrete inheritance).

При этом типе наследования ORM Doctrine создает отдельные таблицы для дочерних классов. При этом каждый класс генерирует таблицы, которые содержат все столбцы (включая и унаследованные). Для того чтобы использовать такой тип наследования, вам необходимо явно вызвать parent::setTableDefinition()
у дочерних классов, как показано ниже:


// models/TextItem.php

class TextItem extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('topic', 'string', 100);
}
}



Теперь давайте создадим модель Comment, расширяющую TextItem, и добавим новый столбец content:

// models/Comment.php

class Comment extends TextItem
{
public function setTableDefinition()
{
parent::setTableDefinition();

$this->hasColumn('content', 'string', 300);
}
}


Теперь в формате YAML:

---
# schema.yml

# ...
TextItem:
columns:
topic: string(100)

Comment:
inheritance:
extends: TextItem
type: concrete
columns:
content: string(300)


Если посмотреть SQL ...

// test.php

// ...
$sql = Doctrine_Core::generateSqlFromArray(array('TextItem', 'Comment'));
echo $sql[0] . "\n";
echo $sql[1];



CREATE TABLE text_item (id BIGINT AUTO_INCREMENT,
topic VARCHAR(100),
PRIMARY KEY(id)) ENGINE = INNODB

CREATE TABLE comment (id BIGINT AUTO_INCREMENT,
topic VARCHAR(100),
content TEXT,
PRIMARY KEY(id)) ENGINE = INNODB

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

ORM Doctrine. Простое наследование (simple inheritance).

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


// models/Entity.php

class Entity extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('name', 'string', 30);
$this->hasColumn('username', 'string', 20);
$this->hasColumn('password', 'string', 16);
$this->hasColumn('created_at', 'timestamp');
$this->hasColumn('update_at', 'timestamp');
}
}



Теперь создаем модель User, расширяющую (наследующую) Entity ...


// models/User.php

class User extends Entity
{ }


И тоже самое для класса Group ...

// models/Group.php

class Group extends Entity
{ }



Вот так это будет выглядеть в формате YAML:

---
# schema.yml

# ...
Entity:
columns:
name: string(30)
username: string(20)
password: string(16)
created_at: timestamp
updated_at: timestamp

User:
inheritance:
extends: Entity
type: simple

Group:
inheritance:
extends: Entity
type: simple


Если посмотреть на SQL, который генерируют эти модели ...

// test.php

// ...
$sql = Doctrine_Core::generateSqlFromArray(array('Entity', 'User', 'Group'));
echo $sql[0];



... то в обоих случаях будет следующее:

CREATE TABLE entity (id BIGINT AUTO_INCREMENT,
username VARCHAR(20),
password VARCHAR(16),
created_at DATETIME,
updated_at DATETIME,
name VARCHAR(30),
PRIMARY KEY(id)) ENGINE = INNODB

Jquery. Работа с массивами значений элементов input.



<script type="text/javascript">
$(document).ready(function() {

...

// Контейнер для значений элементов формы
var videoIds = [];
// Проход по объектам элементов формы с помощью итератора ...
$("input[name=videoIds\\[\\]]").each(function () {
// ... помещаем значение в контейнер
videoIds.push(this.value);
})
// Выводим результат, склеивая значения элементов массива
alert(videoIds.join(', '));

...
});
</script>

<input type="hidden" name="videoIds[]" value="1" />
<input type="hidden" name="videoIds[]" value="2" />
<input type="hidden" name="videoIds[]" value="3" />


В результате мы должны увидеть следующее
1, 2, 3

понедельник, 13 сентября 2010 г.

PHP. Функция set_include_path().

Действие этой функции оказывает влияние только на include и require.
Такие функции, как is_file, is_readable ничего об этом не знают ;-)

воскресенье, 12 сентября 2010 г.

Table Data Gateway (Шлюз к данным таблицы).

Table Data Gateway (Шлюз к данным таблицы).








Объект выступает в качестве шлюза между данными в приложении и в БД. Один объект работает сразу со всеми записями в таблице.

Сочетание SQL-запросов и логики приложения может вызвать достаточно много проблем. Есть разработчики, которые не сильны в SQL, а есть и те, кто в этом преуспел. Администраторы SQL-серверов должны иметь возможность быстро найти SQL-код, чтобы понимать каким образом настраивать и развивать сервера.

Объект шлюза к таблице содержит все запросы SQL для доступа к отдельной таблице или представлению (view): выборка, обновление, вставка, удаление (CRUD). Остальной код, для взаимодействия с БД, обращается к методам объекта шлюза.

Пример: объект шлюза PersonGateway содержит методы для доступа к таблице person в БД. Методы содержат SQL-код для выборки, вставки, обновления и удаления. Объект может содержать специальную выборку, например поиск по компании.

Источник

четверг, 9 сентября 2010 г.

PHP. Шаблоны проектирования. Адаптер.

Шаблон проектирования "Адаптер" используется, когда требуется преобразовать объект одного типа в объект другого типа. Использование этого шаблона, как и всех прочих, повышает чистоту кода и возможность его многократного использования.


// Класс для вывода адреса
class AddressDisplay
{
private $addressType;
private $addressText;

public function setAddressType($addressType)
{
$this->addressType = $addressType;
}

public function getAddressType()
{
return $this->addressType;
}

public function setAddressText($addressText)
{
$this->addressText = $addressText;
}

public function getAddressText()
{
return $this->addressText;
}
}

// Класс адреса электронной почты
class EmailAddress
{
private $emailAddress;

public function getEmailAddress()
{
return $this->emailAddress;
}

public function setEmailAddress($address)
{
$this->emailAddress = $address;
}
}

// Адаптер
class EmailAddressDisplayAdapter extends AddressDisplay
{
public function __construct($emailAddr)
{
$this->setAddressType("email");
$this->setAddressText($emailAddr->getEmailAddress());
}
}

// Использование адаптера
$email = new EmailAddress();
$email->setEmailAddress("user@example.com");

$address = new EmailAddressDisplayAdapter($email);

echo($address->getAddressType() . "\n") ;
echo($address->getAddressText());


Как видно, после реализации шаблона, нам больше нечего беспокоится за то, как EmailAddress преображается в AddressDisplay. И это хорошая новость, особенно если изменится реализация AddressDisplay.
Основное преимущество модульного дизайна в том, чтобы иметь возможность менять минимум кода при изменении бизнес-модели приложения или добавлении нового функционала. Важно помнить об этом даже в тривиальных вещах, таких как передача значений от объекта к объекту.

C++. STL. Константный итератор (constant iterator) и реверсивный итератор (reverse Iterator).

Константный итератор не допускает изменения данных, на которые он ссылается. Можно считать константный итератор указателем на константу. Чтобы получить константный итератор, можно воспользоваться типом const_iterator, предопределенным в различных контейнерах.

... если в контейнере итератор ссылается на первый элемент данных, то реверсивный итератор ссылается на последний ...

vector myvec;
myvec.push_back("Hello, ");
myvec.push_back("kitty!");
vector::const_iterator ci;
for(ci=myvec.begin(); ci!=myvec.end(); ci++) {
print(*ci);
}

// Hello,
// kitty!

vector::reverse_iterator ri;
for(ri=myvec.rbegin(); ri!=myvec.rend(); ++ri) {
print(*ri);
}
// kitty!
// Hello,

PHP. Запуск одиночного тестового класса PHPUnit.


phpunit MyTest path/to/MyTest.php

C++. STL. Контейнер vector.

файл myapp.cpp
#include <iostream>
#include <string>
#include <vector>
using namespace std;

void print(string str) {
cout << str << endl;
}

main()
{
vector<string> myvec;
myvec.push_back("my string 1");
myvec.push_back("my string 2");
myvec.push_back("my string 3");

int i;
for(i=0; i<myvec.size(); i++) {
print(myvec[i]);
}
}


g++ myapp.cpp -o myapp
./myapp

my string 1
my string 2
my string 3

среда, 8 сентября 2010 г.

PHP. PDO. Узнать структуру таблицы MySQL.

Как узнать название полей таблицы в базе данных (ее структуру), используя PDO???
$dbh = new PDO('mysql:dbname=mydb;host=myhost', 'login', 'pwd');
$sth = $dbh->prepare('SHOW COLUMNS FROM mytable');
$sth->setFetchMode(PDO_FETCH_ASSOC);
$sth->execute();
while($row = $sth->fetch()) {
    print_r($row);
}
$sth = null;

PHP. PDO.

$dbh = new PDO('mysql:dbname=test;host=localhost', $username, $password);

// let's have exceptions instead of silence.
// other modes: PDO_ERRMODE_SILENT (default - check $stmt->errorCode()
// and $stmt->errorInfo()) PDO_ERRMODE_WARNING (php warnings)
$dbh->setAttribute(PDO_ATTR_ERRMODE, PDO_ERRMODE_EXCEPTION);

// one-shot query
$dbh->exec("create table test(name varchar(255) not null primary key,
                  value varchar(255));");

// insert some data using a prepared statement
$stmt = $dbh->prepare("insert into test (name, value) values (:name, :value)");
// bind php variables to the named placeholders in the query
// they are both strings that will not be more than 64 chars long
$stmt->bindParam(':name', $name, PDO_PARAM_STR, 64);
$stmt->bindParam(':value', $value, PDO_PARAM_STR, 64);

// insert a record
$name = 'Foo';
$value = 'Bar';
$stmt->execute();

// and another
$name = 'Fu';
$value = 'Ba';
$stmt->execute();

// more if you like, but we're done
$stmt = null;


// get some data out based on user input
$what = $_GET['what'];
$stmt = $dbh->prepare('select name, value from test where name=:what');
$stmt->bindParam('what', $what);
$stmt->execute();

// get the row using PDO_FETCH_BOTH (default if not specified as parameter)
// other modes: PDO_FETCH_NUM, PDO_FETCH_ASSOC,
// PDO_FETCH_OBJ, PDO_FETCH_LAZY, PDO_FETCH_BOUND
$row = $stmt->fetch();
print_r($row);
$stmt = null;


// get all data row by row
$stmt = $dbh->prepare('select name, value from test');
$stmt->execute();
while ($row = $stmt->fetch(PDO_FETCH_ASSOC)) {
    print_r($row);
}
$stmt = null;


// get data row by row using bound ouput columns
$stmt = $dbh->prepare('select name, value from test');
$stmt->execute();
$stmt->bindColumn('name', $name);
$stmt->bindColumn('value', $value)
while ($stmt->fetch(PDO_FETCH_BOUND)) {
    echo "name=$name, value=$value\\n";
}

понедельник, 6 сентября 2010 г.

PHP. basename и pathinfo с кодировкой UTF.

Такие функции как basename, pathinfo в PHP не работают с именами файлов в кодировке UTF и это очень фигово, если не использовать такую функцию:

function pathinfo_utf($path) {

    if (strpos($path, '/') !== false) 
        $basename = end(explode('/', $path));
    elseif (strpos($path, '\\') !== false)
        $basename = end(explode('\\', $path));
    else 
        return false;

    if (!$basename)
        return false;

    $dirname = substr($path, 0,
                   strlen($path) - strlen($basename) - 1);

    if (strpos($basename, '.') !== false) {
        $extension = end(explode('.', $path));
        $filename = substr($basename, 0,
                        strlen($basename) - strlen($extension) - 1);
    } else {
        $extension = '';
        $filename = $basename;
    }

    return array (
            'dirname' => $dirname,
            'basename' => $basename,
            'extension' => $extension,
            'filename' => $filename
    );
}

Спасибо jjoss at mail dot ru, который опубликовал ее на php.net, кажется она работает ;-)

суббота, 4 сентября 2010 г.

Ubuntu. На нетбуке.

Если вы счастливый обладатель нетбука Samsung и решили установить Ubuntu Netbook Remix (в моем случае это Samsung n150 с предустановленной Windows 7) и если у вас что-то вдруг не работает из коробки, например, подсветка экрана при работе от аккумулятора и fn-keys регулирования уровня подсветки, как у меня, то вам необходимо установить полезные пакеты из следующего репозитория

https://launchpad.net/~voria/+archive/ppa

sudo apt-add-repository ppa:voria
sudo apt-get update && sudo apt-get upgrade
sudo apt-get install samsung-tools samsung-backlight


После установки samsung-backlight и samsung-tools все мои мечты сбылись, чего и вам желаю!!!