Drupal hétvége 2013

Bizony, lassan megint elérkezünk az évnek abba a szakaszába, amikor egy egész hétvégét a Drupalnak lehet szentelni. Idén november 16.-án és 17.-én kerül megrendezésre a konferencia. A tavalyi BME épület szerintem nagyon jól bevált, örülök hogy idén is ott lesz. Még nem végleges az program, de biztosan sok előadás fog szólni a készülő D8-ról, így aki érdekel mit hoz a közeljövő Drupal fronton, annak mindenképpen érdemes eljönni.

Magyar számok tól/től ragozása PHP nyelven.

  • php
  • magyar nyelv

Néhány másodpercig kerestem csak kedvenc keresőnkben, hogy létezik-e olyan PHP script amivel a magyar számokat lehet tól/től ragokkal ellátni, de nem találtam ilyet. A dolog pofon egyszerű, de mivel ilyen még nincs a neten (vagy én nem találtam) ezért gondoltam hasznos lehet. Pozitív és negatív egész számokra működik.

Update: 1.000.000 fölötti számokra nem jó, javítani fogom.

Update 2: Ha minden igaz akkor most már nagyon nagy számokra, 10^600-ig is jó. Forrás: wiki

<?php
function magyar_szam_tol_rag($szam) {
 
$absz = abs($szam);
 
  switch (
$absz % 10) {
    case
1:
    case
2:
    case
4:
    case
5:
    case
7:
    case
9:
      return
"$szam-től";
    case
3:
    case
6:
    case
8:
      return
"$szam-tól";
  }

  switch ((
$absz / 10) % 10) {
    case
1:
    case
4:
    case
5:
    case
7:
    case
9:
      return
"$szam-től";
    case
2:
    case
3:
    case
6:
    case
8:
      return
"$szam-tól";
  }
 
  if (
$absz == 0) {
    return
"$szam-tól";
  }
  elseif (
1000 <= $absz && $absz < 1000000) {
    return
"$szam-től";
  }
  else {
    return
"$szam-tól";
  }
}
?>

Ha valahol hibás volna, jelezzétek a hozzászólásoknál.

PCRE találós kérdés

Mutatok egy nagyon egyszerű reguláris kifejezést PHP-val:

<?php
  preg_match
('|[\.-_]+|', $eml, $m);
?>

Szerintetek mire fog ez a minta illeszkedni? Annyit segítek, hogy nem a '.' a '-' és a '_' karakterekből sorozatokra illeszkedik.

Ha nem tudod, akkor lent adok egy kis segítséget.

 

 

 

Ez így már valóban a fenti 3 karaterből állós sorozatra illeszkedik:

<?php
  preg_match
('|[-_\.]+|', $eml, $m);
?>

Ha ez sem segít, akkor van még egy utolsó segítségem.

 

 

 

Ez is csak a '.' a '-' és a '_' katekterekre illeszkedik:

<?php
  preg_match
('|[\.\-_]+|', $eml, $m);
?>

 

 

 

A megfejtés, hogy az első verzióban a '.' és '_' karakterek közötti intervallumnak veszi a kifejezést, ezért egy csomó egyéb dologra is illeszkedni fog.

Drupal futtatása parancssorból (azaz CLI-ből)

Miért is akarjunk mi parancssorból Drupal-t futtatni? Például akkor hasznos ha egy import szkirptet írunk, ami nagyon sokáig is futhat. Vagy ha a futás kimenete olyan információ, amit aztán a linux parancssorból vagy egy bash scriptben akarunk felhasználni.

Oké, van nekünk Batch API-nk a hosszú futásokhoz, meg Drush is van a CLI-hez. De azért nézzük meg , mit tudunk kezdeni egy egyszerű php fájllal.

Először is érdemes belepillantani a Drupal index.php-ba, a cron.php-va, ha még nem tettük meg. Kiderül, hogy ezek faék egyszerű fájlok, így aztán innen fogunk puskázni.

Első naiv próbálkozás

Legyen a cli.php fájl tartalma ez:

<?php
define
('DRUPAL_ROOT', getcwd());
include_once
DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
?>

Futtassuk így:
# php cli.php

Rögtön kapunk is egy csomó hibát, mert nem létezik a REMOTE_ADDR kulcs egy tömbben. Ez a tömb nem lehet más, csak a $_SERVER. Érthető is, hiszen nem böngészőből hívjuk meg a scriptet. Javítsuk ezt a hibát azzal, hogy pótoljuk ezt az értéket.

<?php
$_SERVER
['REMOTE_ADDR'] = '127.0.0.1';
?>

Tegyünk egy kis óvintézkedést, és állítsuk le a szkript futását, ha nem parancssorból futtatjuk. Ezt így tehetjük meg:

<?php
if (php_sapi_name() !== 'cli') {
  exit(
1);
}
?>

Ezzel teljesen kizárjuk a webszervert, így a legtöbb biztonsági kockázatnak elejét vettük.

A teljes kód

Nos nagyjából ennyi, a teljes kód mindössze ennyi:

<?php
define
('DRUPAL_ROOT', getcwd());

if (
php_sapi_name() !== 'cli') {
  exit(
1);
}

$_SERVER['REMOTE_ADDR'] = '127.0.0.1';

include_once
DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
?>

Ezután bármit megtehetünk a kis php szkriptben. Például meghívhatunk egy hook-ot minden modulban így:

<?php
 module_invoke_all
('xmlrpc');
?>

Vagy bármely modul egy tetszőleges függvényét így:

<?php
 import_modulom_import_fuggvenye
();
?>

Fontos, hogy kinek a nevében fut!

Egy dologra viszont oda kell figyelni: a php-t futtató szerver felhasználó. Debian/Ubuntu rendszereken www-data az alapbeállítás, de szervertől függően ez bármi lehet. A fájlkezelés miatt fontos, ugyanis a fájlokat tartalmazó könyvtárban (pl.: sites/default/files) minden fájlnak a webszerver a tulajdonosa, ezzel lehet írni-olvasni a fájlokat. Ha mi egy másik felhasználó nevében futtatjuk a ki import php szkriptünket, ami mondjuk képeket is importál, akkor bizony az új vagy módosított fájloknak más lesz a tulajdonosa. És ez baj, mert akkor később a web-ről már nem tudjuk módosítani, vagy akár törölni ezeket.

Ezerféle módon megoldhatjuk ezt a problémát, a két legegyszerűbbet mutatom be.
Legjobb megoldás, ha a php-t a megfelelő felhasználó nevében futtatjuk. Ha pl. www-data nevében fut az Apache vagy másik webszerver, akkor így:

# sudo -u www-data php cli.php

Erre viszont nincs mindig lehetőség. Egyszerű, de nagyszerű megoldás az is, ha a cli.php futása után egyszerűen átadjuk a megfelelő felhasználónak a files könyvtár tartalmát:

# chown -R www-data sites/default/files

Ez az egész ötlet nekem egy importálás miatt kellett, és nagyon jól bevált. Remélem másnak is hasznos lesz.

MyISAM vs. InnoDB – melyik a gyorsabb?

Legalább egymilliószor feltették már a kérdést, hogy MySQL adabzáis szerver esetén melyik tábla típus a gyorsabb, az InnoDB vagy a MyISAM. És legalább kétmilliószor megválaszolták már. Most én is meg válaszolom.

Műveletek

MyISAM alatt 1 db. SELECT lefuttatása mindig gyorsabb.
MyISAM alatt 1 db. INSERT lefuttatása mindig gyorsabb.
MyISAM alatt 1 db. UPDATE lefuttatása mindig gyorsabb.
MyISAM alatt 1 db. DELETE lefuttatása mindig gyorsabb.

Ugyanez igaz 1.000.000 SELECT-re vagy 1.000.000.000 SELECT-re, de INSERT-re UPDATE-re és DELETE-re is. Ha egyforma utasításokról beszélünk.

Miért? Mert nincsenek tranzakciók.

Valódi alkalmazások

Ha felváltva jönnek az olvasás (SELECT) és az írás (INSERT/UPDATE/DELETE) műveletek, akkor az InnoDB a gyorsabb.

Miért? Mert a MyISAM esetén senki nem tudja olvasni vagy írni a táblát, ha egyvalaki írja.

Egy INSERT és egy SELECT feltartja egymást MyISAM esetén. InnoDB esetén nem, ott egyszerre futnak.

Precízebben: az InnoDB sor szintű lock-ot használ, az MyISAM tábla szintű lock-ot.

Konklúzió

Az InnoDB valódi alkalmazások esetében mindig gyorsabb. Szinte kivétel nélkül. Két ritka kivétel van, amikor a MyISAM gyorsabb lehet:

  1. akkor ha egy táblából csak olvasunk, írások nélkül.
  2. akkor ha egy táblába csak írunk, de nem olvassuk ki.

Az első eset előfordulhat, de általában csak kevés rekordot tartalmazó táblákkal. Szerintem nagyon ritka az az eset, hogy csak olvassuk a táblát és nagyon sok rekord van benne. A második esetet gyakorlatilag kizárhatjuk, minek írnánk egy táblába, ha nem olvassuk.

Egy szó mint száz, valódi alkalmazások esetén az InnoDB-t tábla típust csak nagyon ritkán veri meg a MyISAM sebesség tekintetében.

Oldalak

Feliratkozás Prunk-Éger Edgár RSS csatornájára