За чистый и ясный код!

Статьи на тему программирования под веб, используя PHP, MySQL, Jquery и многое другое

События (events) в MySQL (планировщик заданий аля CRON)

Ноябрь30

Предисловие

Наверное в 99% случаев если необходимо делать операции над данными в БД использовалась связка PHP и CRONа и в скрипте описывались все необходимые запросы. В MySQL 5.1.6 появился планировщик. Теперь можно не терзая указанную выше связку, если она не требует чего-то больше, что не умеет делать MySQL.

Для работы вам понадобится:

сервер БД 5.1.6 и выше; права пользователю на использование этой фичи.

Проверка работоспособности планировщика

Первое, что надо сделать — это удостоверится, что планировщик включен. Это можно сделать по команде

SHOW VARIABLES LIKE '%event%';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| event_scheduler | OFF   |
+-----------------+-------+

Получается он у меня выключен, ну что же можем включить:

SET GLOBAL event_scheduler = ON;

тем самым мы включили его до перезагрузки сервера!!! Что бы планировщик был постоянно включен необходимо в файле конфигурации поставить параметр: event_scheduler=1.

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

ЗАДАНИЕ

Например мы имеем таблицу users и нам каждый день в 00-00 необходимо выбирать всех, кто родился в этот день и записывать данные в табл users_dr (ФИО и пол). Можно конечно обойтись и простой выборкой по текущему дню, но если сайт с высокой нагрузкой, то делать выборку каждый раз это будет смерть БД.

Создание планировщика

Оператор планировщика имеет следующий синтаксис:

CREATE
    [DEFINER = { user | CURRENT_USER }]
    EVENT
    [IF NOT EXISTS]
    event_name
    ON SCHEDULE schedule
    [ON COMPLETION [NOT] PRESERVE]
    [ENABLE | DISABLE | DISABLE ON SLAVE]
    [COMMENT 'comment']
    DO sql_statement;

schedule:
    AT timestamp [+ INTERVAL interval] ...
  | EVERY interval
    [STARTS timestamp [+ INTERVAL interval] ...]
    [ENDS timestamp [+ INTERVAL interval] ...]

interval:
    quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |
              WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |
              DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}

Много букв, но ничего, разберем на нашем примере.

DELIMITER ;;
DROP EVENT IF EXISTS `test_user_dr;;
CREATE EVENT `test_user_dr`
ON SCHEDULE EVERY 1 DAY STARTS '2009-07-19 00:00:00'
ON COMPLETION PRESERVE ENABLE
COMMENT 'таблица дней рождений'
DO
BEGIN
 DROP TABLE IF EXISTS `test`.`users_dr`;
 CREATE TABLE `test`.`users_dr`
   SELECT `fio`,`sex`
   FROM `test`.`users`
   WHERE `dr`=DATE_FORMAT(NOW(),"%d-%m")=DATE_FORMAT(`dr`,"%d-%m")
   ORDER BY `fio` ASC;
END;;
DELIMITER ;

Теперь разберем.

Т.к. в планировщике используется больше одного запроса, то эти запросы необходимо ограничивать директивами BEGIN и END, а для того, что бы MySQL не начал выполнять операции внутри планировщика, нам надо переопределить символ обозначающий конец запроса, по дефолту это ; Оператором DELIMITER ;; мы указываем, что теперь две косые есть конец запроса.

На всякий случай удаляем планировщик DROP EVENT IF EXISTS `test_user_dr` // Создаем новый планировщик `test_user_dr` с параметрами ON SCHEDULE EVERY 1 DAY STARTS ‘2009-07-19 00:00:00’, означает каждый в 00-00-00 начиная с указанной даты, параметр DAY — интервал, может принимать и другие параметры, о них написано выше. Далее говорим ON COMPLETION PRESERVE ENABLE — включаем этот планировщик и если он завершиться ОКОНЧАТЕЛЬНО, то его из памяти не удаляем. Наш планировщик никогда не завершается, т.к. нет директивы ENDS timestamp, но если бы он была и было написано ON COMPLETION NOT PRESERVE, то всё задание удалилось. С комментарием, думаю, все понятно. Далее после слов DO BEGIN идут запросы, которые будут выполняться планировщиком и заканчивает директивой END.

Теперь планировщик будет каждый день начиная с 19 июля 2009 года в полночь делать таблицу пользователей у которых ДР в текущий день.

Удаление планировщика

Тут все просто, используем оператор

DROP EVENT [IF EXISTS] event_name</pre>
В нашем случае
<pre lang="sql">DROP EVENT IF EXISTS `test_user_dr`;</pre>
<h2>Изменение планировщика</h2>
<pre lang="sql">ALTER
    [DEFINER = { user | CURRENT_USER }]
    EVENT event_name
    [ON SCHEDULE schedule]
    [ON COMPLETION [NOT] PRESERVE]
    [RENAME TO new_event_name]
    [ENABLE | DISABLE | DISABLE ON SLAVE]
    [COMMENT 'comment']
    [DO sql_statement]

Например надо изменить время срабатывания, ну например чтобы таблицы ДР обновлялась 2 раза в сутки, тогда следует написать

ALTER EVENT `test_user_dr` ON SCHEDULE EVERY 12 HOUR;

Список планировщиков

Список заданий можно посмотреть 2-мя способами:

1-й покажет все данные по всем планировщикам для БД test

SHOW EVENTS FROM `test`\G;
*************************** 1. row ***************************
                  Db: test
                Name: test_user_dr
             Definer: root@localhost
           Time zone: SYSTEM
                Type: RECURRING
          Execute at: NULL
      Interval value: 12
      Interval field: HOUR
              Starts: 2009-07-19 00:00:00
                Ends: NULL
              Status: ENABLED
          Originator: 0
character_set_client: cp1251
collation_connection: cp1251_general_ci
  Database Collation: cp1251_general_ci
1 row in set (0.00 sec)

2-й Показывает полностью данные для указанного задания

SHOW CREATE EVENT `test_user_dr`\G;
*************************** 1. row ***************************
               Event: test_user_dr
            sql_mode: STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
           time_zone: SYSTEM
        Create Event: CREATE EVENT `test_user_dr` и весь текст планировщика...
character_set_client: cp1251
collation_connection: cp1251_general_ci
  Database Collation: cp1251_general_ci
1 row in set (0.00 sec)

Ну вроде все. Если есть вопросы пишите, буду отвечать.

Ссылки

Официальное руководство

Статья просмотренна 81484 раз, зашло посетителей 28448

Список локалей

Ноябрь28
Компьютеры для юридических лиц, фирм и компаний от adelsy.ru, заходи выбирай как игровой компьютер, так и для бизнеса.

Всем привет.

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

Команда для просмотра локалей на Вашем сервере, кто не знает:

maxnag@nagaychenko:~> cd /usr/lib/locale/
maxnag@nagaychenko:/usr/lib/locale> ls

А вот и список:

aa_DJ            es_BO.utf8           mn_MN
aa_DJ.utf8       es_CL                mn_MN.utf8
aa_ER            es_CL.utf8           mr_IN
aa_ER@saaho      es_CO                mr_IN.utf8
aa_ER.utf8       es_CO.utf8           ms_MY
aa_ET            es_CR                ms_MY.utf8
aa_ET.utf8       es_CR.utf8           mt_MT
af_ZA            es_DO                mt_MT.utf8
af_ZA.utf8       es_DO.utf8           nb_NO
am_ET            es_EC                nb_NO.utf8
am_ET.utf8       es_EC.utf8           nds_DE
an_ES            es_ES                nds_NL
an_ES.utf8       es_ES@euro           ne_NP
ar_AE            es_ES.utf8           ne_NP.utf8
ar_AE.utf8       es_GT                nl_BE
ar_BH            es_GT.utf8           nl_BE@euro
ar_BH.utf8       es_HN                nl_BE.utf8
ar_DZ            es_HN.utf8           nl_NL
ar_DZ.utf8       es_MX                nl_NL@euro
ar_EG            es_MX.utf8           nl_NL.utf8
ar_EG.utf8       es_NI                nn_NO
ar_IN            es_NI.utf8           nn_NO.utf8
ar_IN.utf8       es_PA                no_NO
ar_IQ            es_PA.utf8           no_NO.utf8
ar_IQ.utf8       es_PE                nr_ZA
ar_JO            es_PE.utf8           nso_ZA
ar_JO.utf8       es_PR                oc_FR
ar_KW            es_PR.utf8           oc_FR.utf8
ar_KW.utf8       es_PY                om_ET
ar_LB            es_PY.utf8           om_ET.utf8
ar_LB.utf8       es_SV                om_KE
ar_LY            es_SV.utf8           om_KE.utf8
ar_LY.utf8       es_US                or_IN
ar_MA            es_US.utf8           pa_IN
ar_MA.utf8       es_UY                pa_IN.utf8
ar_OM            es_UY.utf8           pap_AN
ar_OM.utf8       es_VE                pa_PK
ar_QA            es_VE.utf8           pl_PL
ar_QA.utf8       et_EE                pl_PL.utf8
ar_SA            et_EE.iso885915      pt_BR
ar_SA.utf8       et_EE.utf8           pt_BR.utf8
ar_SD            eu_ES                pt_PT
ar_SD.utf8       eu_ES@euro           pt_PT@euro
ar_SY            eu_ES.utf8           pt_PT.utf8
ar_SY.utf8       fa_IR                ro_RO
ar_TN            fa_IR.utf8           ro_RO.utf8
ar_TN.utf8       fi_FI                ru_RU
ar_YE            fi_FI@euro           ru_RU.koi8r
ar_YE.utf8       fi_FI.utf8           ru_RU.utf8
as_IN.utf8       fil_PH               ru_UA
ast_ES           fo_FO                ru_UA.utf8
ast_ES.utf8      fo_FO.utf8           rw_RW
az_AZ.utf8       fr_BE                sa_IN
be_BY            fr_BE@euro           sc_IT
be_BY@latin      fr_BE.utf8           se_NO
be_BY.utf8       fr_CA                se_NO.utf8
ber_DZ           fr_CA.utf8           shs_CA
ber_MA           fr_CH                sh_YU
bg_BG            fr_CH.utf8           sh_YU.utf8
bg_BG.utf8       fr_FR                sid_ET
bn_BD            fr_FR@euro           sid_ET.utf8
bn_BD.utf8       fr_FR.utf8           si_LK
bn_IN            fr_LU                sk_SK
bn_IN.utf8       fr_LU@euro           sk_SK.utf8
bo_CN            fr_LU.utf8           sl_SI
bo_IN            fur_IT               sl_SI.utf8
br_FR            fy_DE                so_DJ
br_FR@euro       fy_NL                so_DJ.utf8
br_FR.utf8       ga_IE                so_ET
bs_BA            ga_IE@euro           so_ET.utf8
bs_BA.utf8       ga_IE.utf8           so_KE
byn_ER           gd_GB                so_KE.utf8
byn_ER.utf8      gd_GB.utf8           so_SO
ca_AD            gez_ER               so_SO.utf8
ca_AD.utf8       gez_ER@abegede       sq_AL
ca_ES            gez_ET               sq_AL.utf8
ca_ES@euro       gez_ET@abegede       sr_ME
ca_ES.utf8       gl_ES                sr_RS
ca_FR            gl_ES@euro           sr_RS@latin
ca_FR.utf8       gl_ES.utf8           ss_ZA
ca_IT            gu_IN                st_ZA
ca_IT.utf8       gv_GB                st_ZA.utf8
crh_UA           gv_GB.utf8           sv_FI
csb_PL           ha_NG                sv_FI@euro
cs_CZ            he_IL                sv_FI.utf8
cs_CZ.utf8       he_IL.utf8           sv_SE
cy_GB            hi_IN                sv_SE.iso885915
cy_GB.utf8       hi_IN.utf8           sv_SE.utf8
da_DK            hr_HR                ta_IN
da_DK.utf8       hr_HR.utf8           ta_IN.utf8
de_AT            hsb_DE               te_IN
de_AT@euro       hsb_DE.utf8          te_IN.utf8
de_AT.utf8       hu_HU                tg_TJ
de_BE            hu_HU.utf8           tg_TJ.utf8
de_BE@euro       hy_AM                th_TH
de_BE.utf8       hy_AM.armscii8       th_TH.utf8
de_CH            id_ID                ti_ER
de_CH.utf8       id_ID.utf8           ti_ER.utf8
de_DE            ig_NG                ti_ET
de_DE@euro       ik_CA                ti_ET.utf8
de_DE.utf8       is_IS                tig_ER
de_LU            is_IS.utf8           tig_ER.utf8
de_LU@euro       it_CH                tk_TM
de_LU.utf8       it_CH.utf8           tl_PH
dz_BT            it_IT                tl_PH.utf8
el_CY            it_IT@euro           tn_ZA
el_CY.utf8       it_IT.utf8           tr_CY
el_GR            iu_CA                tr_CY.utf8
el_GR.utf8       iw_IL                tr_TR
en_AU            iw_IL.utf8           tr_TR.utf8
en_AU.utf8       ja_JP.eucjp          ts_ZA
en_BE            ja_JP.shiftjisx0213  tt_RU@iqtelif.UTF-8
en_BE@euro       ja_JP.sjis           tt_RU.utf8
en_BE.utf8       ja_JP.utf8           ug_CN
en_BW            ka_GE                uk_UA
en_BW.utf8       ka_GE.utf8           uk_UA.utf8
en_CA            kk_KZ                ur_PK
en_CA.utf8       kk_KZ.utf8           ur_PK.utf8
en_DK            kl_GL                uz_UZ
en_DK.utf8       kl_GL.utf8           uz_UZ@cyrillic
en_GB            km_KH                ve_ZA
en_GB.iso885915  kn_IN                vi_VN
en_GB.utf8       ko_KR.euckr          vi_VN.tcvn
en_HK            ko_KR.utf8           wa_BE
en_HK.utf8       ku_TR                wa_BE@euro
en_IE            ku_TR.utf8           wa_BE.utf8
en_IE@euro       kw_GB                wo_SN
en_IE.utf8       kw_GB.utf8           xh_ZA
en_IN            ky_KG                xh_ZA.utf8
en_IN.utf8       lg_UG                yi_US
en_NG            lg_UG.utf8           yi_US.utf8
en_NZ            li_BE                yo_NG
en_NZ.utf8       li_NL                zh_CN
en_PH            lo_LA                zh_CN.gb18030
en_PH.utf8       lt_LT                zh_CN.gbk
en_SG            lt_LT.utf8           zh_CN.utf8
en_SG.utf8       lv_LV                zh_HK
en_US            lv_LV.utf8           zh_HK.utf8
en_US.iso885915  mai_IN               zh_SG
en_US.utf8       mg_MG                zh_SG.gbk
en_ZA            mg_MG.utf8           zh_SG.utf8
en_ZA.utf8       mi_NZ                zh_TW
en_ZW            mi_NZ.utf8           zh_TW.euctw
en_ZW.utf8       mk_MK                zh_TW.utf8
es_AR            mk_MK.utf8           zu_ZA
es_AR.utf8       ml_IN                zu_ZA.utf8
es_BO            ml_IN.utf8

Всем удачи, Максим.

Статья просмотренна 44598 раз, зашло посетителей 13821

Парсинг CSV файлов на PHP

Ноябрь28

В данной статье речь пойдет о распознавании  формата CSV.

Что такое формат данных CSV, пояснять не буду, прочитайте об этом на http://ru.wikipedia.org/wiki/CSV.

И так, у меня был исходный файл в CSV формате, с кодировкой UTF-8, необходимо было его разобрать, для последующего заноса в базу данных.

Небольшой фрагмент этого файла

Имя;Фамилия;Мыло;Разное
Максим;Нагайченко;max_nag[at]meta.ua;программист
"?Мария";"????µ";intik_79[at]mail.ru;
;;some@email.com

Как видно здесь встречаются кириллица, латиница, умляуты (расширенная латиница).

Для парсинг я воспользовался стандартной ф-цией PHP — fgetcsv.

При разборе на виндовс машине вообще никаких проблем не возникло, все было разобрано, разложено — в общем все как надо, осталось только занести в БД.

При разборе этого файла на линукс машине возникли проблемы — кириллица вообще не хотела распознаваться, если она не была обрамлена — кавычкой («). Решение нашлось за 30 минут и выпитой чашкой чая.

Оказывается, необходимо указывать корректную локаль при работе с данной ф-цией, об этоя я прочитал в комментариях к указанной выше ф-ции.

setlocale(LC_ALL, 'ru_RU.UTF-8');

Если у вас в проекте используется несколько языков интерфейса, то при переключении, не забудьте переключить локаль. Особенно это важно, если для перевода интерфейса используется ф-ция gettext().

Всем удачи, Максим.

Статья просмотренна 72966 раз, зашло посетителей 26374

Переменные переменных в PHP

Ноябрь26

В этой статье речь пойдет о так называемых — «переменные переменных«.

Что же это??? Наверняка каждый программист php сталкивался с переменными, которые имеют нестандартное название, точнее нестандартное создание переменных ($$ и тд), вот примеры

$$someVariable

${'rrr'}

$f()

Все это так называемые — «переменные переменных«. Это значение переменной, которое может стать самой переменной.

Разберем как они работают. Перед Вами небольшой код в котором я постарался собрать все примеры.

<?php
function myFunc()
{
echo 'Hello&lt;br&gt;';
}

$myVariable = 'myFunc';

$myVariable();
/*----------------------------------------*/
$someVar = 'hello';

$$someVar = 'Auf Wiedersehen&lt;br&gt;';

echo $hello;
/*----------------------------------------*/
$втораяПеременная = '123';

$$втораяПеременная = 'apple';

echo ${'123'};
?>

На экране будет выведено:

Hello
Auf Wiedersehen
apple

Я объясню на одном примере :

function myFunc()
{
echo 'Hello<br>';
}

$myVariable = 'myFunc';
$myVariable();

Тут видно, что создана ф-ция с названием myFunc которая выведет слово Hello<br>.  Мы конечно можем просто вызвать ф-цию через обращение к ней myFunc(); , но можно воспользоваться и другой конструкцией. Создать переменную (любую) потом присвоить ей значение — это само название ф-ции. И применив к переменной скобки () мы вызовем на исполнение данную ф-цию.

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

В последнем примере, как Вы думаете, почему я применил такой подход ${‘123’}; зачем эти фигурные скобки???? Ответ — т.к переменная не может начинаться с цифры, а $втораяПеременная = ‘123’; , точнее значение переменной, которое потом преобразуется в переменную, именно цифра, то для экранирования, обхода этого ограничения, используется ${‘someVar’} конструкция.

И еще, название переменных может быть не только на латинице, как пишется в некоторых книгах [a-zA-Z_0-9], но даже и иероглифы $? = ‘123’; (только если кодировка файла UTF-8, естественно).

Полезная ссылка:

http://www.php.net/manual/en/language.variables.php

Всем удачи, Максим.

Статья просмотренна 44760 раз, зашло посетителей 11709

  

Облако тегов

cli csv dump events form Kohana locale models MySQL mysqldump orm PHP tools trigger validate газ газовый счетчик итоги кеширование переменные

Облако тегов плагина WP Cumulus для WordPress требует для просмотра Flash Player 9 или выше.

Я на твиттере!

  • у твиттера тоже бывают перерывы...

Календарь

Ноябрь 2009
Пн Вт Ср Чт Пт Сб Вс
    Дек »
 1
2345678
9101112131415
16171819202122
23242526272829
30  

Сейчас на сайте