пятница, 25 апреля 2025 г.

Экспорт из PHP в CSV большого кол-во данных

В PHP существует удобный инструмент php://output, который, подобно конструкциям print и echo, позволяет выводить данные в выходной буфер, не загружая память сервера. Как его использовать? Прежде чем привести пример, отмечу, что в ООП экспорт данных (например, сохранение) должен выполняться в контроллере, а бизнес-логика (выборка, агрегация и т.д.) — в модели. Ниже представлен простой пример без использования ООП:

// Отключаем кэширование
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Expires: 0');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');

// Устанавливаем заголовки для CSV
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="export.csv"');
header('Content-Transfer-Encoding: binary');

// Пример получения данных (заменить на реальную выборку из БД)
$list = [
    ['_id' => 1, 'date' => time(), 'user' => 'John'],
    ['_id' => 2, 'date' => time(), 'user' => 'Jane'],
    // ... другие данные
];

// Заголовки для CSV
$titles = ['ID', 'Date', 'User'];

// Открываем поток php://output
$df = fopen('php://output', 'w');
if ($df === false) {
    die('Ошибка открытия потока php://output');
}

// Записываем заголовки
fputcsv($df, $titles);

// Записываем данные
foreach ($list as $row) {
    // Проверяем, не прервано ли соединение
    if (connection_aborted()) {
        fclose($df);
        die('Соединение с клиентом прервано');
    }

    fputcsv($df, [
        $row['_id'],
        date('Y-m-d H:i:s', $row['date']),
        $row['user'],
        // Добавить другие поля, если нужно
    ]);

    // Очищаем буфер для экономии памяти
    flush();
}

// Закрываем поток
fclose($df);

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

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

В чем еще проблема? Несмотря на экономию серверной памяти, у метода есть недостаток: во время потоковой передачи данных в файл скрипт продолжает выполняться. Однако время выполнения скрипта ограничено (обычно около 15 секунд, если не изменять настройки). Если сохранение, например, 50 тысяч записей занимает больше 15 секунд, возникнет ошибка fatal error из-за превышения времени выполнения.

Источник

четверг, 6 марта 2025 г.

Мне 46 и я в Батуми

 Я уже 3 год в Батуми. Здесь родилась моя дочка Мирая, недавно ей исполнился 1 год. Мы здесь вместе с семьёй и нам здесь нравится. Рядом море, пальмы и горы.

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

Шпаргалка по GIT

 

Пример использования Git

В первую очередь необходимо поставить Git:

pkg_add -r git

Затем создаем пару ssh ключей, если не создавали ее ранее:

ssh-keygen
cat ~/.ssh/id_rsa.pub

Заходим на БитБакет, создаем git-репозиторий под новый проект, а в свойствах аккаунта прописываем свой открытый ssh-ключ. Затем клонируем репозиторий:

cd ~/projects/haskell
git clone git@bitbucket.org:afiskon/hs-textgen.git
cd hs-textgen

Делаем какие-то изменения:

echo test > TODO.TXT

Добавляем новый файл в репозиторий и делаем коммит:

git add TODO.TXT
git commit -a

Поскольку я не указал описание коммита, запускается редактор VIM, с помощью которого я и ввожу описание. Затем я отправляю все сделанные мною изменения на БитБакет:

git push origin

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

git branch new_feature
git checkout new_feature

Работаем с этой веткой. Если ничего хорошего не вышло, возвращаемся к основной ветке (она же «trunk» или «ствол»):

git checkout master

Если вышло что-то хорошее, мержим ветку в master (о разрешении конфликтов рассказано в следующем параграфе):

git commit -a # делаем коммит всех изменений в new_feature
git checkout master # переключаемся на master
git merge new_feature # мержим ветку new_feature

Не забываем время от времени отправлять наш код на BitBucket:

git push origin

Если мы правим код с нескольких компьютеров, то перед началом работы не забываем «накатить» в локальный репозиторий последнюю версию кода:

git pull origin

Работа в команде мало чем отличается от описанного выше. Только каждый программист должен работать со своей веткой, чтобы не мешать другим программистам. Одна из классических ошибок при начале работы с Git заключается в push’е всех веток, а не только той, с которой вы работали. Вообще я бы советовал первое время перед выполнением каждого push делать паузу с тем, чтобы подумать, что и куда сейчас уйдет. Для большей безопасности советую при генерации ssh-ключей указать пароль. Тогда каждый запрос пароля со стороны Git будет для вас сигналом «Эй, ты делаешь что-то, что затронет других».

Для работы с Git под Windows можно воспользоваться клиентом TortoiseGit. Если память не подводит, для работы ему нужен Git for Windows. Для генерации ключей можно воспользоваться утилитой PuTTyGen. Только не забудьте экспортировать открытый ключ в правильном формате, «Conversions → Export OpenSSH key».

Следует отметить, что мне лично TortoiseGit показался не слишком удобным. Возможно, это всего лишь дело привычки, но мне кажется намного удобнее работать с Git из консоли, чем с помощью контекстного меню в Проводнике.

Шпаргалка по командам

В этом параграфе приведена сухая шпаргалка по командам Git. Я далеко не спец в этой системе контроля версий, так что ошибки в терминологии или еще в чем-то вполне возможны. Если вы видите в этом разделе ошибку, отпишитесь, пожалуйста, в комментариях.

Создать новый репозиторий:

git init project-name

Если вы планируете клонировать его по ssh с удаленной машины, также скажите:

git config --bool core.bare true

… иначе при git push вы будете получать странные ошибки вроде:

Refusing to update checked out branch: refs/heads/master
By default, updating the current branch in a non-bare repository
is denied, because it will make the index and work tree inconsistent
with what you pushed, and will require 'git reset --hard' to match
the work tree to HEAD.

Клонировать репозиторий с удаленной машины:

git clone git@bitbucket.org:afiskon/hs-textgen.git

Если хотим пушить один код в несколько репозиториев:

git remote add remotename git@gitlab.example.ru:repo.git

Добавить файл в репозиторий:

git add text.txt

Удалить файл:

git rm text.txt

Текущее состояние репозитория (изменения, неразрешенные конфликты и тп):

git status

Сделать коммит:

git commit -a -m "Commit description"

Сделать коммит, введя его описание с помощью $EDITOR:

git commit -a

Замержить все ветки локального репозитория на удаленный репозиторий (аналогично вместо origin можно указать и remotename, см выше):

git push origin

Аналогично предыдущему, но делается пуш только ветки master:

git push origin master

Запушить текущую ветку, не вводя целиком ее название:

git push origin HEAD

Замержить все ветки с удаленного репозитория:

git pull origin

Аналогично предыдущему, но накатывается только ветка master:

git pull origin master

Накатить текущую ветку, не вводя ее длинное имя:

git pull origin HEAD

Скачать все ветки с origin, но не мержить их в локальный репозиторий:

git fetch origin

Аналогично предыдущему, но только для одной заданной ветки:

git fetch origin master

Начать работать с веткой some_branch (уже существующей):

git checkout -b some_branch origin/some_branch

Создать новый бранч (ответвится от текущего):

git branch some_branch

Переключиться на другую ветку (из тех, с которыми уже работаем):

git checkout some_branch

Получаем список веток, с которыми работаем:

git branch # звездочкой отмечена текущая ветвь

Просмотреть все существующие ветви:

git branch -a # | grep something

Замержить some_branch в текущую ветку:

git merge some_branch

Удалить бранч (после мержа):

git branch -d some_branch

Просто удалить бранч (тупиковая ветвь):

git branch -D some_branch

История изменений:

git log

История изменений в обратном порядке:

git log --reverse

История конкретного файла:

git log file.txt

Аналогично предыдущему, но с просмотром сделанных изменений:

git log -p file.txt

История с именами файлов и псевдографическим изображением бранчей:

git log --stat --graph

Изменения, сделанные в заданном коммите:

git show d8578edf8458ce06fbc5bb76a58c5ca4a58c5ca4

Посмотреть, кем в последний раз правилась каждая строка файла:

git blame file.txt

Удалить бранч из репозитория на сервере:

git push origin :branch-name

Откатиться к конкретному коммиту (хэш смотрим в «git log»):

git reset --hard d8578edf8458ce06fbc5bb76a58c5ca4a58c5ca4

Аналогично предыдущему, но файлы на диске остаются без изменений:

git reset --soft d8578edf8458ce06fbc5bb76a58c5ca4a58c5ca4

Попытаться обратить заданный commit:

git revert d8578edf8458ce06fbc5bb76a58c5ca4a58c5ca4

Просмотр изменений (суммарных, а не всех по очереди, как в «git log»):

git diff # подробности см в "git diff --help"

Используем vimdiff в качестве программы для разрешения конфликтов (mergetool) по умолчанию:

git config --global merge.tool vimdiff

Отключаем диалог «какой mergetool вы хотели бы использовать»:

git config --global mergetool.prompt false

Отображаем табы как 4 пробела, например, в «git diff»:

git config --global core.pager 'less -x4'

Создание глобального файла .gitignore:

git config --global core.excludesfile ~/.gitignore_global

Разрешение конфликтов (когда оные возникают в результате мержа):

git mergetool

Создание тэга:

git tag some_tag # за тэгом можно указать хэш коммита

Удаление untracked files:

git clean -f

«Упаковка» репозитория для увеличения скорости работы с ним:

git gc

Иногда требуется создать копию репозитория или перенести его с одной машины на другую. Это делается примерно так:

mkdir -p /tmp/git-copy
cd /tmp/git-copy
git clone --bare git@example.com:afiskon/cpp-opengl-tutorial1.git
cd cpp-opengl-tutorial1.git
git push --mirror git@example.com:afiskon/cpp-opengl-tutorial2.git

Следует отметить, что Git позволяет использовать короткую запись хэшей. Вместо «d8578edf8458ce06fbc5bb76a58c5ca4a58c5ca4» можно писать «d8578edf» или даже «d857».

Дополнение: Также в 6-м пункте Мини-заметок номер 9 приводится пример объединения коммитов с помощью git rebase, а в 10-м пункте Мини-заметок номер 11 вы найдете пример объединения двух репозиториев в один без потери истории.

Работа с сабмодулями

Более подробно сабмодули и зачем они нужны объясняется в заметке Простой кроссплатформенный OpenGL-проект на C++. Здесь упомянем самое главное.

Добавить сабмодуль:

git submodule add https://github.com/glfw/glfw glfw

Инициализация сабмодулей:

git submodule init

Обновление сабмодулей, например, если после git pull поменялся коммит, на который смотрит сабмодуль:

git submodule update

Удаление сабмодуля производится так:

  1. Скажите git rm --cached имя_сабмодуля;
  2. Удалите соответствующие строчки из файла .gitmodules;
  3. Также грохните соответствующую секцию в .git/config;
  4. Сделайте коммит;
  5. Удалите файлы сабмодуля;
  6. Удалите каталог .git/modules/имя_сабмодуля;

Дополнительные материалы

В качестве источников дополнительной информации я бы рекомендовал следующие:

 

Источник: https://eax.me/git-commands/
Публикую у себя, потому что домены авторов иногда не продлевается, а такой контент исчезает. Blogspot работает и ничего не просит годами.

четверг, 16 мая 2019 г.

Подключение javascript в yii2

Inline js

Во view можно подключить произвольный javascript код:

$var = 123;
//начало многосточной строки, можно использовать любые кавычки
$script = <<< JS
    function foo() {
        return $var; //можно использовать переменные
    }
JS; //маркер конца строки, обязательно сразу, без пробелов и табуляции

$this->registerJs($script, yii\web\View::POS_READY);

получим сразу перед закрытием body:


<script type="text/javascript">
jQuery(document).ready(function () {
    function foo() {
        return 123;
    }
});</script>

другие варианты места подключения скрипта: (документация)
  • POS_HEAD: перед тегом </head>
  • POS_BEGIN: после тэга <body>
  • POS_END: перед тэгом </body>
  • POS_LOAD: оборачивается в jQuery(window).load(). Note that by using this position, the method will automatically register the jQuery js file.
  • POS_READY: оборачивается вjQuery(document).ready(). This is the default value. Note that by using this position, the method will automatically register the jQuery js file.

js-файл

$this->registerJsFile('url/to/file.js',  ['position' => yii\web\View::POS_END]);
источник  

вторник, 7 мая 2019 г.

Подсветка кода для blogger

Пересмотрел кучу вариантов для подсветки кода в blogger, единственное на данный момент рабочее решение это https://highlightjs.org

О том как его добавить в блог читаем здесь - https://81code.blogspot.com/2016/04/syntax-highlighter-blogger.html

Перед тем как вставить код, его нужно обработать например в HTML Escape
Еще для себя добавил плагин показа номеров строк - https://github.com/wcoder/highlightjs-line-numbers.js/

понедельник, 6 мая 2019 г.

Находим в тексте ссылки youtube и конвертим их в embed видео

Код:

function convertYoutube($string) {
    return preg_replace(
        "/\s*[a-zA-Z\/\/:\.]*youtu(be.com\/watch\?v=|.be\/)([a-zA-Z0-9\-_]+)([a-zA-Z0-9\/\*\-\_\?\&\;\%\=\.]*)/i",
        "<iframe src=\"//www.youtube.com/embed/$2\" allowfullscreen></iframe>",
        $string
    );
}

Источник: stackoverflow.com

четверг, 8 июня 2017 г.

Minexcoin - новая эра крипто платежей!


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

Некоторые из таких монет можно собирать без вложений и потом на фоне роста продавать на бирже в обмен на биткоины! Цена таких монет может варьироваться от 4 -5 цнтов до 50 долларов за 1 монету!

Одной из таких монет является Minexсoin‏ - MNC Получить её можно бесплатно только на предстарте, а именно до 13 июня 2017 года, в дальнейшем её можно будет только купить!

Чтобы получить монету нужно перейти по ссылке https://minexcoin.com/ref/11079 и зарегистрироваться на сайте

Подключить свой аккаунт Facebook или Twitter, подписаться на email-рассылку и проявлять активность в социальных сетях.

Каждую неделю Вы будете получать определенное количество монет исходя из вашей активности, а после выхода на биржу обменяете их на биткоин! Вот так все просто!
Скопировал отсюда

вторник, 30 мая 2017 г.

yii2 полезные мелочи

Как в yii2 проверить isNewRecord в afterSave()

Теперь алгоритм проверки после сохранения такой:
app\models\Model
public function afterSave($insert, $changedAttributes)
    {
        if ($insert) {
                // Да это новая запись (insert)
        } else {
                // Нет, старая (update)
        }
        parent::afterSave($insert, $changedAttributes);
}

 

Не находит action из контроллера Not Found (#404)

В yii2 есть особенность с именование action в отличие от yii1:
в контроллере создаем action
public function actionLastNews()
{
////
}
при стандартных rules этот экшн будет доступен по адресу: /last-news
Эта мелочь может попортить немало нервов.

Подключение javascript в yii2

Inline js

Во view можно подключить произвольный javascript код:
$var = 123;
//начало многосточной строки, можно использовать любые кавычки
$script = <<< JS
    function foo() {
        return $var; //можно использовать переменные
    }
JS;
//маркер конца строки, обязательно сразу, без пробелов и табуляции
$this->registerJs($script, yii\web\View::POS_READY);
получим сразу перед закрытием body:
<script type="text/javascript">
jQuery(document).ready(function () {
    function foo() {
        return 123;
    }
});</script>
</body>
другие варианты места подключения скрипта: (документация)
  • POS_HEAD
  • POS_BEGIN: после тэга
  • POS_END: перед тэгом
  • POS_LOAD: оборачивается в jQuery(window).load(). Note that by using this position, the method will automatically register the jQuery js file.
  • POS_READY: оборачивается вjQuery(document).ready(). This is the default value. Note that by using this position, the method will automatically register the jQuery js file.
  • js-файл

    $this->registerJsFile('url/to/file.js',  ['position' => yii\web\View::POS_END]);
     
    Скопировано отсюда 

    среда, 28 декабря 2016 г.

    5 лет независимости

    28 декабря 2016 года стукнуло 5 лет как вышел наш первый релиз CMS Open Real Estate. С тех пор много чего было интересного и не очень. Трудно взбираться в гору, особенно в начале пути. Но мы смогли добиться относительной стабильности. Недавно я поймал себя на мысли, что фраза из сказки про Алису -

    Нужно бежать со всех ног, чтобы только оставаться на месте, а чтобы куда-то попасть, надо бежать как минимум вдвое быстрее!

    очень точно передает нашу жизнь. И если прекратить бежать, то можно упасть. Поэтому нужно бежать всегда. Что я и делаю ) Но смотря на результаты, хотелось бы бежать быстрее. Все таки я бегу не так быстро.

    О становлении нашей компании с картинками можно почитать здесь.

    четверг, 25 августа 2016 г.

    Получаем координаты районов с помощью API OSM

    Итак, всё до безобразия просто, делаем запрос:
    http://nominatim.openstreetmap.org/search?format=json&q=%D0%9A%D1%80%D0%BE%D0%BD%D1%88%D1%82%D0%B0%D0%B4%D1%82%D1%81%D0%BA%D0%B8%D0%B9%20%D1%80%D0%B0%D0%B9%D0%BE%D0%BD,%20%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3&polygon_geojson=1
    Всё  Получаем в ответ geojson (массив с географическими координатами) и делаем с ним что хотим.
    Например, я решил обработать его в несколько ином виде, чтобы скармливать Яндекс.Картам. Для этого я накидал простеньку функцию на PHP:
    function areaCoordsParser($search)
    {
        $query = http_build_query([
            'format' => 'json',
            'q' => $search,
            'polygon_geojson' => 1,
        ]);
        $url = "http://nominatim.openstreetmap.org/search?$query";
        $response = json_decode(file_get_contents($url), true);
        $result = [];
        if ($response[0]['geojson']['type'] === 'MultiPolygon') {
            $coords = $response[0]['geojson']['coordinates'];
            foreach ($coords as $coord) {
                $temp = [];
                foreach ($coord[0] as $item) {
                    $temp[] = array_reverse($item);
                }
                $result[] = $temp;
            }
        } elseif ($response[0]['geojson']['type'] === 'Polygon') {
            $coords = $response[0]['geojson']['coordinates'][0];
            foreach ($coords as $coord) {
                $result[] = array_reverse($coord);
            }
        }
        return $result;
    }
    echo json_encode(areaCoordsParser('Адмиралтейский район, Санкт-Петербург'));
    Источник - http://zabolotskikh.com/tips/kak-poluchit-koordinaty-rayonov/

    среда, 20 февраля 2013 г.

    Блоги о PHP

    Статьи
    Alt-F4 | Статьи, истории и блоги web-разработчиков
    Oleg Smirnoff - Профиль Google
    phpQuery шпоргалка | Блог saintista
    Ускоряем JetBrains PhpStorm в “тяжелых” проектах
    Jeck labs
    Блог Teimos'а
    W3 Kirby :)
    записки Rulexec: Июль 2010
    Блог программиста
    Парсинг от А до Я
    Gautama It: О стандартизации различных CMS.
    Мощь SVG и media queries | Евгений Степанищев | последние 15
    Антон Шевчук: блог web-разработчика
    Всё о web-разработке и продвижении сайтов
    Владимир Осипов
    Владимир Осипов - личный блог
    Блог.ру - butjok - Бутёк здесь!
    Блог о программировании
    SimpleTDS 1.3 - JackSoft&Xeonix MOD (MySQL) | JackSoft и SEO
    Блог интернет-разработчика
    Время выполнения скрипта <> PHP <> Programmerz.Ru
    Dumpz.org
    Deerua about Coding -> Заметки с тегом «minijQuery» @ deer.org.ua
    Блог программиста | Статьи | Другое | Массовый Google Page Rank Checker на PHP
    Динамический список dofollow-блогов | Андрюха Воробьев – сила в желании - dofollow блог
    33 коровы - RIA разработка, Flex, Action Script, AIR, Eclipse, Monkey script
    Home page of Sb0y || Домашняя страничка Sb0я
    John Conde .net
    Дом Figaroo
    От простого к сложному
    Веб перцы - сделай свой сайт острее!
    Brain.log » php кодинг
    Chodex.ru - Linux, Php, Highload, Kohana, Android
    CTAPbIu_MABP's BLOG
    GTAlex о Заработке в сети интернет - способы, инструменты, SEO, раскрутка и разработка сайтов, поисковая оптимизация, сателлиты, блоги, CMS движки
    Блог Герасимова Константина/Просмотр статей/
    PHP. Прелестный язык, на котором обычно пишут ногами » Исходники проектов
    Блог ГО: PHP, JavaScript, Memcached, Redis, Mercurial
    За чистый и ясный код!
    Записки профессора » Класс для загрузки файлов на сервер
    Записки о web-программировании
    Записки Зверобоя
    Блог о веб-разработке
    О PHP и о жизни…

    четверг, 5 июля 2012 г.

    Вывод даты словами PHP

    Код - пример #1
    1
    2
    3
    4
    5
    6
    7
    $date = /* timestamp из БД */ ;
    $d = time() - $date;
     
    if ($d < 60) echo $d . ' сек. назад';
    elseif ($d < 3600) echo round($d / 60) . ' мин. назад';
    elseif ($d < 86400) echo round($d / 3600) . ' ч. назад';
    else echo round($d / 86400) . ' дн. назад';

    четверг, 23 февраля 2012 г.

    Вешаем Fancybox на кнопку button

    С помощью плагина fancybox можно делать замечательные галереи и попапы. В документации есть примеры. Но как повесить его на кнопку? Вот так:
    Код - пример #1
    1
    2
    3
    4
    <form action="/ACTION/FastFindObj" method="post">
      <input name="fastfind" class="fastfind" value="3463" type="text">
      <input name="weiter" type="submit">
    </form>

    И используем:

    Код - пример #1
    1
    2
    3
    4
        $("form").fancybox();
        $("input").fancybox();
        $("input[name='weiter']").fancybox();
    
    Больше примеров здесь

    пятница, 30 декабря 2011 г.

    Бесплатная CMS Open Real Estate на Yii

    Недавно, мы выпустили бесплатную CMS Open Real Estate на Yii. Открытый исходный код, open source. Это мой первый опыт, работы над open source проектом такого уровня.

    В качестве системы контроля версий использовали Mercurial hg. По моему это самое лучшее решение, до этого пробовал CVS, SVN, GIT.

    И самое главное набрался опыта работы с Yii framework и планирую продолжить работу с ним. Постепенно, понимаешь, насколько в нем все грамотно реализовано и сколько много труда в него вложено.

    пятница, 21 октября 2011 г.

    Как в Denwer импортировать через консоль дамп базы mysql

    Поражаюсь какой у блогера тупой WYSWIG приходится раставлять тег br руками для переносов, потому что если сделать перенос по умолчанию какой есть в настройках, получается УЖАС.

    Иногда приходится импортировать большие дампы sql, через phpmyadmin делать это проблематично, т.к. по умолчанию стоит ограничение на файлы не больше 2Мб. Сегодня надо было импортировать 90Мб, через консоль импортировалось без проблем.

    Win+R, cmd, Enter

    p:

    cd P:\usr\local\mysql5\bin\
    mysql_run_to_import_dumps.exe

    mysql> \r base_name

    mysql> \. dump_file



    где p - виртуальный диск, создаваемый денвером
    base_name - имя базы
    dump_file - файл с дампом базы (включая путь)

    Найдено здесь )

    пятница, 14 октября 2011 г.

    Как получить выбранные элементы checkbox в массив jQuery

    var selectedItems = new Array();
    $("input[@name='itemSelect[]']:checked").each(function() {selectedItems.push($(this).val());});
     
    if (selectedItems .length == 0) {
        alert("Please select item(s) to delete.");
    } else {
        $.ajax({
            type: "POST",
            url: "/ajax_do_something.php",
            data: "items=" + selectedItems.join('|'),
            dataType: "text",
            success: function (request) {
                document.location.reload();
            },
            error: function(request,error){
                alert('Error deleting item(s), try again later.');
            }
        })
    } 
    
    Нашел здесь

    среда, 3 августа 2011 г.

    Паттерн Одиночка - Singleton Pattern в PHP

    Код - пример #1
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <?php
    // PHP5
    class Logger {
    
        static private $instance = NULL;
    
        /* Возвращаем ссылку на одиночку  */
        static function getInstance() {
        
            /* Если объект еще не создан, создаем */
            if (self::$instance == NULL) {
                self::$instance = new Logger();
            }
            
            return self::$instance;
        }
    
        /* Запрещаем прямое создание */
        private function __construct() {
        
        }
    
        /* Запрещаем клонирование */
        private function __clone() {
        
        }
    
    }

    вторник, 31 мая 2011 г.

    Абстрактная фабрика - (Abstract Factory)

    Список паттернов
    Код - пример #1
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    <?php
    /*
    
    Абстрактная фабрика - (Abstract Factory)
    
    Фабрика должна возвращать объекты. Но так как она абстрактная, то изначально нужно
    описать абстрактный класс фабрики, и абстрактные объекты которые она будет производить. 
    
    Дале мы описываем реализации классов фабрик на основе абстрактной фабрики и реализации класса объектов
    которые она производит. Тем самым у нас есть различные варианты фабрик и объектов с одинковыми
    интерфейсами, что может быть удобно.
    
    Далее привожу код. Есть абстрактная фабрика машин. Абстрактный класс машин. Создаем классы фабрики
    "ford" и "vaz" и классы ford_machine и vaz_machine. Фабрики будут производить объект "машины", но
    свойство "начинака" этих "машин" будет отличаться, прям как в реальной жизни.
    
    */
    
    abstract class abstract_machine_factory {
        function generate_sedan() {
            return new machine('sedan');
        }
        
        function generate_universal() {
            return new machine('universal');    
        }
        
        function generate_hatchback() {
            return new machine('hatchback');    
        }
    }
    
    abstract class abstract_machine {
        protected $_param;
    
        function __construct($type = 'sedan') {
            $this->_param = array();
            $this->_param['type'] = $type;
        }    
        
        function run() {
            echo 'brrrrrrrrrrrrrr ...';
        }
        
        function get_all_param() {
            return $this->_param;
        }
    }
    
    class vaz_machine extends abstract_machine {
        function __construct($type = 'sedan') {
            parent::__construct($type);
    
            $this->_param['firm'] = 'vaz';
        }
    
        function run() {
            echo 'tr tr pr tr tr pr ...';
        }
    }
    
    class vaz_factory extends abstract_machine_factory {
        function generate_sedan() {
            return new vaz_machine('vedro');
        }
        
        function generate_universal() {
            return new vaz_machine('taz');    
        }
        
        function generate_hatchback() {
            return new vaz_machine('korito');    
        }    
    }
    
    class ford_machine extends abstract_machine {
        function __construct($type = 'sedan') {
            parent::__construct($type);
            
            $this->_param['firm'] = 'ford';
        }
    
        function run() {
            echo 'rrrrrrrrrrrrrrrrr ...';
        }
    }
    
    class ford_factory extends abstract_machine_factory {
        function generate_sedan() {
            return new ford_machine('sedan', 'ford');
        }
        
        function generate_universal() {
            return new ford_machine('universal');    
        }
        
        function generate_hatchback() {
            return new ford_machine('hatchback');    
        }    
    }
    
    /* Фабрика ford_factory производит машины */
    $ford_factory = new ford_factory();
    $ford_machine = $ford_factory->generate_sedan();
    
    deb($ford_machine->get_all_param());
    deb($ford_machine->run());
    
    /* Фабрика vaz_factory производит машины, функции одинаковые но результат (объекты) разные */
    $vaz_factory = new vaz_factory();
    $vaz_machine = $vaz_factory->generate_sedan();
    
    deb($vaz_machine->get_all_param());
    deb($vaz_machine->run());
    
    /* В результате мы видим на экране:
    
    Array
    (
        [type] => sedan
        [firm] => ford
    )
    
    rrrrrrrrrrrrrrrrr ...
    
    Array
    (
        [type] => vedro
        [firm] => vaz
    )
    
    tr tr pr tr tr pr ...
    
    */
    
    function deb($mVar) {
        echo("<PRE>");
        print_r($mVar);
        echo("</PRE>");
    }
    
    

    Список паттернов