PHP » MyEgo.cz - Radek Hulán webzine

MyEgo.cz

home foto blogy mywindows.cz kontakt

Užitečné funkce pro PHP - díl 3.

PHP 14.08.2004

Jeden z častých problémů weblogů je ten, že obsahují velké množství externích linků, takže de-facto reprezentují takovou malou link-farmu. Nic dobrého pro Google Page Rank. S PHP se to dá velice vhodně řešit. V případě BLOG:CMS je to celé možné napsat jako plugin.

Kód používá jednu z nejmocnějších funkcí v PHP, a to preg_replace_callback. Je dobré se s ní pořádně seznámit.

Vlastní implementace je pak poměrně jednoduchá. Uvedený objekt nám převede libovolný text tak, že veškeré externí linky budou směrovat na Váš vlastní web a otevírány přes proměnnou url. Ve spojení s NP_Cache je to možné dělat i za běhu serveru, nikoliv jen při ukládání.

<?php
class SEO {
 // inicializace
 function SEO(){
   global $_SERVER;
   $this->server = $_SERVER['HTTP_HOST'];
   $this->redirect = '/redirect/';
 }
 // převede externí linky v textu na
 // URL typu /redirect/?url=http://externi
 function _SEO(&$text){
   $text = preg_replace_callback(
   '/<a(.*?)href=[\"|\'](.*?)[\"|\']/',
   array(&$this, 'myLink'),
   $text);
 }
 // callback funkce, převede linky, které nejsou na moji
 // doménu, a obsahují URI na SEO-friendly formát
 function myLink($m){
   if (strstr($m[2],$this->server) || 
       ( !strstr($m[2],'http://') && 
         !strstr($m[2],'//') &&
         !strstr($m[2],'ftp://') ) )
     return '<a'.$m[1].'href="'.$m[2].'"';
   else
     return '<a'.$m[1].'href="'.
      $this->redirect.'?url='.$m[2].'"';
 }
} // end class SEO
?>

Užitečné funkce pro PHP - díl 2.

PHP 31.07.2004

V tomto díle seriálu publikuji skript na základní a automatizovanou kontrolu formulářů na straně serveru, a jejich před-vyplňování, v případě, že formulář nebyl vyplněn korektně, a je nutné je opravit.

function check($field,$type,$chars=''){
 $field=htmlspecialchars(trim($_POST[$field]));
 $error='';
 switch ($type){
  case 'email':
   if (preg_match(
    '/^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+.[A-Za-z]{2,5}$/', 
    $field)) return;
   $error='Emailová adresa není platná.';
   break;
 case 'string':
   if (!isset($chars)) $chars=2;
   if (strlen($field)>=$chars) return;
   $error="Tato položka musí mít minimálně $chars znaků.";
   break;
 case 'number':
   if (!isset($chars)) $chars=0;
   if ($chars==0 && !is_numeric($field)) 
     $error="Položka nebyla zadána správně.";
   if ($chars==0 && is_numeric($field) && intval($field)<0) 
     $error="Položka nebyla zadána správně.";
   if ($chars>0) 
   if (!preg_match("/d{".strval($chars)."}/",$field)) 
     $error="Toto číslo musí mít právě $chars znaků.";
   break;
 case 'ico':
   if (!is_numeric($field)) 
     $error='IČ nemá správný formát.';
   break;
 case 'equal':
   if (!isset($field) || !isset($_POST[$chars])) 
     $error='Položka není shodná s předchozí';
   if (strcmp($field,$_POST[$chars])!=0) 
     $error='Tato položka ('.
       $field.
       ') není shodná s předchozí ('.
       $_POST[$chars].')';
   break;
 default:
   die('Chybná konfigurace systému');
   break;
 }
 if (!empty($error)) {
 echo "<p style='color:red'>Chyba: <em>$error</em></p>n";
 $this->isok=false;
 }
} /* end check */

Uvedenou funkci poté můžeme používat pro kontrolu stringových, numerických položek, emailů, IČ organizace (musí být modulo 11), případně rovnosti 2 vložených položek (například 2x vkládaného emailu či hesla).

Užitečné funkce pro PHP - díl 1.

PHP 29.07.2004

V tomto seriálu budu publikovat jednoduché funkce v PHP, které jsou ovšem velice užitečné pro běžné programování redakčního systému.

Vytvoření náhodného hesla pro uživatele

function createPassword($length){
 $vowels = array('a', 'e', 'i', 'o', 'u');
 $cons = array('b', 'c', 'd', 'g', 'h', 'j', 'k', 'l', 
               'm', 'n', 'p', 'r', 's', 't', 'u', 'v', 
               'w', 'tr', 'cr', 'br', 'fr', 'th', 'dr', 
               'ch', 'ph', 'wr', 'st', 'sp', 'sw', 'pr',
               'sl', 'cl');
 $num_vowels = count($vowels);
 $num_cons = count($cons);
 $password = '';
 for($i = 0; $i < $length; $i++)
   $password .= 
     $cons[rand(0, $num_cons - 1)] . 
     $vowels[rand(0, $num_vowels - 1)];
 return substr($password, 0, $length);
}

Zaslání hlaviček (pokud je příjemce umí)

function serverVar($name) {
 return $_SERVER[$name];
}
function sendContentType($contenttype, $charset = 'utf-8') {
 $accept=false;
 if ($contenttype == 'application/xhtml+xml') {
  if (stristr(serverVar("HTTP_ACCEPT"),"application/xhtml+xml")) {
   if (preg_match("/application\/xhtml\+xml;q=0(\.[1-9]+)/i",serverVar("HTTP_ACCEPT"), $matches)) {
    $xhtml_q = $matches[1];
    if (preg_match("/text\/html;q=0(\.[1-9]+)/i",serverVar("HTTP_ACCEPT"), $matches)) {
     $html_q = $matches[1];
     if($xhtml_q >= $html_q) $accept=true;
    }
   } else
   $accept=true;
  }
  if (stristr(serverVar("HTTP_USER_AGENT"),"W3C_Validator")) $accept=true;
 }
 // cannot accept xhtml+xml
 if (!$accept && ($contenttype == 'application/xhtml+xml')) $contenttype='text/html';
 // content type
 header('Content-Type: ' . $contenttype . '; charset=' . $charset);
}

PunBB - sympatické a rychlé fórum

PHP 23.06.2004

PunBB je fórum, které není zatíženo žádným grafickým balastem, tar.bz2 download má jen 90kB (!), je extrémně rychlé i na pomalých linkách a má přitom vše, co potřebujete, včetně exportu posledních příspěvků v RSS/XML formátu. Navíc, je vydáno v GNU GPL licenci. Na naprostou většinu potřeb je phpBB zcela zbytečně nabobtnalé, PunBB je zde vhodnější. Dostupný je dokonce i konvertor z phpBB do PunBB :)

Co je nového v PHP 5 (díl 4/5)

PHP 22.06.2004

V tomto díle se podíváme na další objektová rozšíření PHP 5. Jedním z nich je podpora pro konstanty v rámci třídy. Příklad?

class _trida{
 const constant = "constant";
}
echo "_trida::constant = " . _trida::constant . "\n";

V PHP 5 je možno odkazovat v návratových typech funkcí na metody instancí tříd, což v PHP 4 možno není. Příklad?

class _prvni{
 function doSomething() {
  print "prvni\n";
 }
}
class _druhy{
 function doSomething() {
  print "druhy\n";
 }
}
function _cislo($cislo) {
 switch ($cislo) {
  case "prvni": return new _prvni();
  case "druhy": return new _druhy();
 }
}
_cislo("prvni")->doSomething();
_cislo("druhy")->doSomething();

Co je nového v PHP 5 (díl 3/5)

PHP 18.06.2004

Se slušnou podporou objektů v PHP 5 souvisí i podpora pro lepší typovou kontrolu tříd. Konečně! Nicméně, není to podpora ve fázi kompilace, ale pochopitelně ve fázi runtime, tedy běhu programu. Tento příklad nám ilustruje "class hints":

interface _prvni { function a(_prvni $_prvni); }
interface _druhy { function b(_druhy $_druhy); }
class _treti implements _prvni, _druhy {
 function a(_prvni $_prvni) { // ... }
 function b(_druhy $_druhy) { // ... }
}
$a = new _treti;
$b = new _treti;
$a->a($b);
$a->b($b);

Co je nového v PHP 5 (díl 2/5)

PHP 17.06.2004

Ve druhém díle se podíváme na další rozšíření objektové koncepce PHP 5. Jedním z dalších podstatných rozšíření jsou abstraktní metody třídy (abstract), s tím, že třída, která obsahuje abstraktní metody (není definována jejich implemetace), musí být také typu abstract.

Je pochopitelné, že není možné vytvořit instanci abstract třídy, je nutné vytvořit návaznou třídu, která danou metodu již implemetuje, a zde vytvoříme instanci. Příklad?

abstract class AbstractClass {
  abstract public function test();
}
class ImplementedClass extends AbstractClass {
 public function test() {
   echo "ImplementedClass::test() called\n";
 }
}
$o = new ImplementedClass;
$o->test();

Co je nového v PHP 5 (díl 1/5)

PHP 16.06.2004

PHP 5 přináší spoustu výborných změn. Jedná se hlavně o změnu jeho objektové koncepce. Většině "taky-programátorů" to bude jedno, nevyužívají ani potenciálu PHP 4, nicméně, lidem jako já, co znají výborně C++, sedne PHP 5 mnohem lépe. Jeho implementace objektů se totiž zjevně nechala inspirovat C++ a Javou.

Třída bude mít konsktruktory (což má nakonec částečně již teď) a desktruktory:

class _metodaA {
 var $x;
 function __construct($x) {
   $this->x = $x;
 }
 function display() {
   print($this->x);
 }
 function __destruct() {
   print("bye bye");
 }
}
$o1 = new _metodaA(4);
$o1->display();

Třída bude mít protected (je k nim umožněn přístup i přímým potomkům) a private (přístup k nim mají jen třídy samotné, v nichž jsou definovány) proměnné a rovněž metody. Dosavadní kód (PHP 4) je považován, jako by všechny metody byly typu public.

class Foo {
 private function aPrivateMethod() {
  echo "Foo::aPrivateMethod() called\n";
 }
 protected function aProtectedMethod() {
  echo "Foo::aProtectedMethod() called\n";
  $this->aPrivateMethod();
 }
}
class Bar extends Foo {
  public function aPublicMethod() {
   echo "Bar::aPublicMethod() called\n";
   $this->aProtectedMethod();
  }
}
$o = new Bar;
$o->aPublicMethod();

Jak zrychlit Váš web 10x? (konkrétní návod)

PHP 31.05.2004

Uvedené řešení předpokládá, že Váš web je generován dynamicky, v tomto případě docílíte skutečně cca 10-ti násobného zrychlení Vašeho webu, nicméně, díky zde uvedeným algoritmům je zrychlení 3-4 násobné i po statické XHTML stránky.

V čem spočívá tento algoritmus? Nejdříve, proveďte kompresi Vašeho CSS a JavaScriptu, jak píšu v předchozím článku.

Následně přistoupíme ke kompresi online generovaných PHP stránek, a k vytváření XHTML statických variant stránek, a to plně automaticky.

Pro 10x rychlejší web Vám potom postačí, když na začátku Vaší stránky uvedete následující:

<?php
$statickeXHTML = new Cache();
$statickeXHTML->start();
?>

A na konci následující:

<?php 
$statickeXHTML->finish();
?> 

Jednoduché, ne?

Jak na (šablonu) RSS 2.0 v PHP?

PHP 17.05.2004

Posílal jsem včera Jirkovi Lahvičkovi, weblogy.cz, šablonu pro RSS 2.0, aby měl její zapracování na jeho web poněkud rychlejší. A myslím, že by to mohlo pomoci více lidem, takže, uvádím jednoduchý algoritmus pro vytvoření RSS 2.0 šablony v PHP.

Jednotlivé funkce jsou komentované přímo v kódu, takže nepotřebují moc dalšího komentáře:

// exportuje posledních 20 článků jako RSS
function exportRSSS(){
 putHeader();
 $q=mysql_query(
  'select title, body, link, '.
  '       UNIX_TIMESTAMP(datum) as dt '.
  'from items '.
  'order by dt desc '.
  'limit 0,20');
 while ($row=mysql_fetch_object($q)) 
  putItem($row);
 putEnd();
}