Peter Rehm's Blog

apple,development,life & more

Symfony2 Render String with Twig

without Comments

At some point you might find the need to render templates from an string rather
than an actual file. This is needed for dynamic templates.

This is not possible with the default Symfony2 configuration, however it is easy to
adjust the configuration.

I ended up adding the Twig_Loader_String to the Loader chain with teh following
service configuration:

CODE:
    newi.core.twig.stringloader:
        class: Twig_Loader_String
        tags:
            - { name: twig.loader }


With having this small snippet in the service.yml of one of your bundles you can
render strings with the normal twig instance from the DI container.

CODE:
    $renderedString = $this->get('twig')->render('Hello my name is {{ name }}!', array($name => 'Peter'));

Posted by Peter Rehm

05/26/2014 at 01:32:35 PM

Defined tags for this entry: , ,

PHP 5.5 Opcache in Development

without Comments

PHP 5.5 comes with the Zend Opcache built in. There are also recommended
settings for production which needs to be adjusted for development.

In development you usually dont want to wait until you see your latest changes.
Therefore you need to set the revalidate_freq to 0 in order to revalidate the
files on each request. My development configuration looks like following:

CODE:
opcache.enable=On
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=0
opcache.fast_shutdown=1
opcache.enable_cli=1


To manually clear the opcache just execute the following in your command
line:

CODE:
php -r 'opcache_reset();'


NOTE: In case you are going to use Zend OPcache together with Xdebug,
be sure that Xdebug is loaded after OPcache. "php -v" must show Xdebug
after OPcache.

Posted by Peter Rehm

07/14/2013 at 12:36:34 PM

Defined tags for this entry: ,

Installation PEAR/PECL/autoconf/intl/icu auf Mac OSX Mountain Lion

without Comments

Installation PEAR/PECL/autoconf/intl/icu auf Mac OSX Mountain Lion

- Install PECL & PEAR

CODE:
cd /usr/lib/php
sudo php install-pear-nozlib.phar


- Add to php.ini

CODE:
include_path = ".:/usr/lib/php/pear"
extension_dir = "/usr/lib/php/extensions/no-debug-non-zts-20090626"


- Update pear channels

CODE:
sudo pear channel-update pear.php.net
sudo pecl channel-update pecl.php.net
sudo pear upgrade-all


- Install ICU from http://site.icu-project.org/download/48#ICU4C-Download

CODE:
tar -xzvf icu4c-4_8_1_1-src.tgz
cd icu/source/
./runConfigureICU MacOSX
make
sudo make install


If you get something linke this...


configure: error: in `/Users/peterrehm/Downloads/icu/source':
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details
./runConfigureICU: ./configure failed


you have to install the apple command line tools which you will find
under the following URL for the appropriate OS version like Mountain Lion.

CODE:
https://developer.apple.com/devcenter/mac/index.action


then you should be able to install it..

CODE:
sudo pecl install intl


If you have autoconfi missing go for that:

CODE:
curl -O http://ftp.gnu.org/gnu/autoconf/autoconf-latest.tar.gz
tar -xzvf autoconf-latest.tar.gz
cd autoconf-2.69/


Now you should add "extension=intl.so" to php.ini and restart apache. Here you go.

Posted by Peter Rehm

08/01/2012 at 09:11:24 PM

Defined tags for this entry: , ,

PEAR unter OSX Leopard installieren

with 1 Comment

Im folgenden wird in aller kürze beschrieben, wie man PEAR unter
OSX 10.5 Leopard installiert. Dies sollte unter den vorherigen OSX
Versionen sicher ähnlich funktionieren.

Auf meinem lokalen System habe ich PHP5 von entropy.ch am laufen, da
ich unbedingt die GD-Lib benötige. Dies hat nur Einfluss auf die Ablage
der php.ini. Dies muss eben von den auf dem jeweilig auf dem System vorhandenen
Gegebenheit abhängig gemacht werden.

Wir werden in /usr/local/ installieren, und dem System gestatten die TEMP-Files
in /usr/local/temp abzulegen.

CODE:
sudo mkdir /usr/local/temp
sudo chmod -R 777 /usr/local/temp
sudo mkdir /usr/local/share/pear
sudo chmod -R 777 /usr/local/share/pear


Im nächsten Schritt wird go-pear ausgeführt.

CODE:
curl http://pear.php.net/go-pear | php


Hier muss bei den Pfaden der 1. auf /usr/local geändert werden.
Alle anderen Einstellungen können in der Regel beibehalten werden.

Während der Installation kommt dann die Warnung, dass der PEAR Pfad
noch nicht in der php.ini vorhanden ist, und es deswegen zu Problemen
mit der Verwendung von den PEAR Scripts kommen kann.

Hier kommen wir an den Punkt wo es wichtig ist, zu wissen, wo die
Konfigurationsdatei des Webservers liegen muss. Dies kann man einfach
über ein kurzes Script herausfinden:

CODE:
<? phpinfo(); ?>


Im Browser die Datei ansehen und nach folgender Zeile suchen.

CODE:
Configuration File (php.ini) Path /usr/local/php5/lib


Hier muss die php.ini für den Webserver liegen, die php.ini für
das Command-Line-Interface (CLI) unabhängig davon in /etc/

Standardgemäß ist eine php.ini.default in /etc/. Diese kopieren
und modifizieren wir zunächst.

CODE:
sudo cp /etc/php.ini.default /etc/php.ini
sudo nano /etc/php.ini


Nun nach dem Eintrag include_path suchen und diesen um "/usr/local/share/pear"
ergänzen. Bei mir sah dies nach der Anpassung so aus.

CODE:
include_path=".:/usr/local/share/pear"


Ist eine php.ini in dem Config-Path des Webservers vorhanden bearbeiten
wir diese, ansonsten kopieren wir die Datei /etc/php.ini an die gewünschte
Stelle

CODE:
sudo cp /etc/php.ini /usr/local/php5/lib/php.ini


Abschließend muss noch der Webserver neu gestartet werden, dann ist PEAR
einsatzfähig.

CODE:
sudo apachectl restart


Anmerkung: Kann PEAR von der Konsole nicht mit dem Befehl pear aufgerufen werden,
ist /usr/local/bin nicht korrekt in den SHELL-Pfaden eingetragen, und sollte nachgetragen
werden. Tipp: echo $PATH zum überprüfen in der SHELL eingeben.

Posted by Peter Rehm

01/02/2008 at 11:16:31 AM

Posted in PHP

Defined tags for this entry: , ,

jpgraph und utf-8 daten

with 6 Comments

Wer sich wundert wieso die Texte der erzeugten Graphen mittels jpgraph
in kryptischen Buchstaben dargestellt werden, obwohl gültige Daten in UTF-8
angeliefert wurden, ist nur einen kleinen Schritt von der Lösung entfernt.

Die Ursache des Problems liegt darin dass die Standardschriftarten von jpgraph
kein UTF-8 darstellen können.

Daher kann man sich einfach wie auch auf der jpgraph Seite angegeben ein
entsprechendes Schriftpaket herunterladen. Ich hab mich in meinem Fall für
Verda entschieden.Dies bekommt man hier: http://www.gnome.org/fonts/

Die Schirften lädt man sich herunter und lädt Sie in ein beliebiges Verzeichnis.

Nun muss nur noch das Verzeichnis der Library bekannt gemacht werden:

CODE:
DEFINE("TTF_DIR",dirname(_file_) . '/../../ttf-bitstream-vera-1.10/');


Nun muss man noch mittels SetFont angeben, wo welche Schrift eingesetzt werden
soll. Mir ist es allerdings nicht gelungen die Schriftart für die Beschriftung in den
Netzdiagrammen (jpgraph_radar.php) festzulegen, daher musste ich manuell
die Standardschrift ändern, indem ich in jpgraph.php und jpgraph_radar.php FF_FONT1
durch FF_VERA ersetzt habe.

Nun sollten alle Umlaute auch angezeigt werden können.

Posted by Peter Rehm

10/01/2007 at 11:35:00 PM

Posted in PHP

Defined tags for this entry: , ,

Weitere Lektion in der Umlautproblematik

with 2 Comments

Nachdem ich in einem früheren Blog Eintrag empfohlen habe, alle Daten aus
Speicherplatzgründen die im UTF-8 Format sind in z.b. dem latin1 charset abzulegen,
muss ich dem nun komplett wiedersprechen.
Bei einem durchschnittlichen Projekt lädt man sich deutlich mehr Ärger auf,
als dass man dadurch Vorteile durch Speicherplatzersparnis erzielt.

In meiner Situation sah das dann so aus, dass ich ca. 8 Stunden damit beschäftigt
war, alle Datenbanken meiner Kunden umzustellen, was enorm händische Arbeit
erforderte.

Im Ist-Zustand war es nun auch so, dass mittels phpMyAdmin logischerweise
alle Umlaute kaputt angezeigt wurde, und man nicht oder nur mit hohem manuellen
Aufwand direkt die Daten bearbeiten konnte.

Ausgangssituation
Datenbank mit latin1 als Standardcharset, alle Tabellen latin1, und UTF-8 Daten darin gespeichert.

Ziel
Datenbank & Tabellen UTF-8, und alle Inhalte UTF-8
Ich habe mich für utf8_general_ci entschieden, der unterschied zu utf8_unicode_ci liegt nur in
der Abhandlung von Sortierreihenfolgen. Dies kann man aber im Detail dem MySQL Manual entnehmen.

1.) Datenbank Backup erstellen
Gehen wir einfach mal auf nummer sicher, um die Daten auch sicher nicht
endgültig zu zerstören.

2.) Umwandeln aller Tabellen voll automatisch, und davon sollen auch alle
Text und Varchar Felder umgewandelt werden. Manch einer wird hier noch anpassungen
vornehmen müssen, da ich keine Char Felder umwandle, da die nicht benötigt
werden. ACHTUNG! Das Script basiert wie alle meine Code Snippets auf adodb,
kann aber Problemlos auf die von MySQL zur Verfügung stehenden Funktionen
portiert werden.

CODE:
<?php
// fetch all tables
$data = $cfg['db']->pExecute("SHOW
TABLES");
while($row = $data->FetchRow())
{
$sres = $cfg['db']->pExecute("DESCRIBE ".($row[0]));
while( $column = $sres->FetchRow())
{
// if column is text or varchar, convert
if(strpos($column['Type'],'text')!==false || strpos($column['Type'],'char')!==false
|| strpos($column['Type'],'varchar')!==false)
{
$cfg['db']->Execute("ALTER TABLE ".($row[0])." CHANGE ".($column['Field'])." ".($column['Field'])." ".($column['Type'])." CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL");
}
}

// confert now also full table
$cfg['db']->Execute("ALTER TABLE ".$row[0]." DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci");
}
?>


3.) Manuelles Umwandeln der Datenbank
Ich habe mich dazu entschieden die eigentliche Datenbank händisch umzuwandeln,
da ich mich eh mit der Datenbank verbinden musste. Dazu habe ich dann folgendes
SQL Statement eingegebn

CODE:
ALTER DATABASE `dbname` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci


4.) Exportieren der Daten
Nun werden die Daten der kompletten Datenbank exportiert, nicht aber die
Struktur. Dies wird für die meisten am besten mittels einer grafischen Oberfläche
wie phpMyAdmin erledigt. Hier kann man dies mit weigen Mausklicks erreichen.

5.) Umwandeln des Datendumps
Nun wandeln wir einfach noch die "kaputten Zeichen" zurück in UTF8.
In meinem Fall und in den meisten wird folgendes Script hinreichend sein.
Dazu muss eine Datei data.sql im gleichen Verzeichnis wie das eigentliche
PHP Skript sein.

CODE:
<?php
$str=file_get_contents('data.sql');

$bad_char=array("ä","ö","ü","Ä","Ö","Ü","ß");
$right=array('ä','ö','ü','Ä','Ö','Ü','ß');

$bla=str_replace($bad_char,$right,$str);

echo $bla;

?>


6.) Abschließende Arbeiten
Um die ganze Aktion abzuschließen, muss nur noch die Datenbank geleert werden,
un der neue Dump eingelesen werden. Dann sollte man die Umlaute alle
im entsprechenden Format in der Datenbank haben.

Nun werden einige aber sicher zerstörte Umlaute in der Ausgabe haben,
und sich wundern warum. Dies liegt an der MySQL Verbindung die einen
Befehl zu beginn benötigt um UTF8 sauber zu behandeln.

CODE:
$cfg['db']->Execute("SET names utf8");


Nun sollte es endlich geschafft sein, und man sollte sich nun hoffentlich
wieder wichtigeren Dingen widmen können :-)

Achja, heikel ist dann auch das string handling an manchen stellen, daher sollte man auf
die mb_* funktionen von PHP zurückgreifen.


Posted by Peter Rehm

08/16/2007 at 02:38:50 AM

Posted in PHP

Defined tags for this entry: , ,

gängige PHP Fehler - Tipps & Tricks

with 2 Comments

Neulich wurde ich gebeten, mir "kurz" ein kleines PHP Skript anzusehen,
und bei der Fehlersuche zu helfen. Dabei ist mit allerdings sehr schnell
aufgefallen dass einige grundlegende Unschönheiten zu finden sind.

Daher will ich anhand des mir zugesandten Codes einige Tipps zur PHP Entwicklung
geben.



  1. register_globals

    Ein immer wieder auftrendes Problem ist die register globals Geschichte,
    da PHP einem lange Zeit die Freiheit ließ, auf die POST Variable 'test' auf
    zwei Arten zuzugreifen. Entweder als $test, oder per $_POST['test'].
    Nutzt man erstere Variante kann man sich nie sicher sein, woher der
    Inhalt der Variablen eigentlich stammt, und man vergisst leicht einen
    vielleicht gefährlichen Inhalt zu escapen. Sofern die Möglichkeit besteht
    ist es sogar empfehlenswert register_globals auszuschalten. Aber man
    sollte es sich zumindest immer angewöhnen, auf POST/GET/REQUEST variablen
    immer mittels den dafür vorgesehenen superglobalen Arrays zuzugreifen.




  2. SQL Injections

    Eine große Gefahr stellen vor allem im Zusammenhang mit register_globals
    die SQL Injections dar, über die nicht gewollter SQL Code eingeschleußt
    werden kann. Um hier nicht auszuschweifen sollte man sich immer angewöhnen,
    Inhalt der manipuliert sein kann, zu escapen. Eine einfach Möglichkeit
    hierzu bietet mysql_real_escape_string(). Man sollte sich wenigstens
    angewöhnen den Inhalt immer zu escapen. Es empfiehlt sich auch eine
    eigene Funktion dafür zu nehmen, dass man später auch noch andere
    Verfahren einsetzen könnte, indem man nur eine Funktion überarbeiten
    muss. Hier ein Beispiel:



    CODE:
    /**
    * easy accesible handle to escape all db strings
    * @param string $string string which should be escaped to be put into an sql statement
    * @return string returns the escaped string
    */
    function escapeDB($string)
    {
    global $run;
    if(is_numeric($string))
    {
    return $string;
    } else {
    return $run['db']->qstr($string,get_magic_quotes_gpc());
    }
    }



  3. Variablen

    Man sollte Variablen immer klein schreiben, und Umlaute sollten nicht
    eingesetzt werden. Es ist meist auch recht angenehm die äquivalente englische
    Bezeichnung für Variablen zu verwenden. EIn unschönes Beispiel:



    CODE:
     '$Arbeitsverhaeltnis', '$Kündigungsfrist', '$Sonstiges'



  4. Fehlermeldungen

    Fehlermeldungen sollte man am besten immer beherzigen. PHP kennt verschiedene
    Modi, je nach "wichtigkeit" eines Fehlers. Meist werden die NOTICE's
    ausgeblendet. Allerdings sind NOTICES oft auch recht hilfreich,
    da man erkennt wo man z.B. eine noch nicht initialisierte Variable
    verwendet. Es empfiehlt sich meistens alle Fehlermeldungen anzuzeigen.
    Die macht man wie folgt:


    CODE:
    error_reporting(E_ALL);

    Vor allem gefährlich ist das manuelle Unterdrücken von Fehlermeldungen
    mittels dem @ Operator. Diesen sollte man auch nicht einsetzen, da dadurch
    die Fehlersuche oft erschwert sein kann.





Dies mal nur als kurze Zusammenfassung.

Posted by Peter Rehm

06/07/2007 at 03:49:13 PM

Posted in PHP

Defined tags for this entry: ,

PHP5/PHP5 method_exists

without Comments

Wenn mann dynamisch Methoden aus einer Klasse aufrufen möchte, kommt man
vermutlich an method_exists() kaum vorbei.

Heute musste ich allerdings feststellen, dass PHP4 alle Klassennamen im lowercase überprüft,
PHP5 hingegen so wie es geschrieben wurde. Dies führte natürlich in meinem aktuellen Projekt
zu massiven Schwierigkeiten.

Es bleibt kaum eine andere Lösung, als sich selber eine lowercase Version von method_exists anzufertigen.
Die könnte wie folgt aussehen.

CODE:
function _method_exists($class,$method)
{
$classMethods = array_map('strtolower', get_class_methods($class));

if(in_array(strtolower($method),$classMethods))
{
return true;
} else {
return false;
}
}


Das hab ich dann implementiert, und seither funktioniert alles so wie man es verwenden sollte.

Achja und wenn wir gerade beim Thema sind, man wird auch schnell feststellen, dass
call_user_method deprecated ist und daher nicht mehr eingesetzt werden sollte.
Zumindest laut meiner PHP4 version, im Manual konnte ich dazu nicht viel finden.

Dies kann man aus dem Weg schaffen, indem man call_user_func() oder call_user_func_array()
mit folgenden Parametern aufruft.

CODE:
call_user_func(array(&$object,'my_method_name'));

Posted by Peter Rehm

03/31/2007 at 07:02:11 PM

Posted in PHP

Defined tags for this entry:

MSSQL to MySQL konvertieren

without Comments

In einem aktuellen Projekt stand ich vor der Herausforderung, dass die bisherige Datenbank
in MSSQL gehalten wurde, und ich die Datenbank nur umständlich über ein Weboberfläche
"verwalten" konnte.

Da ich wenigstens die aktuelle Datenstruktur ansehen wollte, den Code der zu dem Projekt
gehört kann eh nicht weiterverwendet werden, musste ich irgendwie ein SQL Statement
erzeugen, was mit dem Tool aber nicht möglich war.

Dann stieß ich auf das MySQL Migration Toolkit, mit welchem man an sich
komfortabel eine MSSQL Datenbank auslesen könnte, und direkt in eine MySQL Datenbank
schreiben kann. Allerdings war, wie nicht anders zu erwarten, der SQL Server nicht von außen
zugänglich.

Die einzige Lösung die somit noch blieb war über ein PHP/ASP Skript, was direkt auf dem
Server liegen kann und soch somit auch verbinden kann. Nach längerer Suche stieß ich auf
das Greenlight SQL Tool.

Aus dem heruntergeladenen ZIP Archiv muss man nur noch die dumpdb.php hochladen und
anpassen. In meinem Fall wollte ich eine MSSQL DB auslesen und in ein MySQL Format bringen.

Standardmäßig sieht der erste teil der Config so aus

CODE:
$dbpasswd = @$HTTP_POST_VARS["dbpasswd"];
$dbhost = (! empty($HTTP_POST_VARS["dbhost"])) ? $HTTP_POST_VARS["dbhost"]
    : "localhost";
$dbname = @$HTTP_POST_VARS["dbname"];
$dbuser = @$HTTP_POST_VARS["dbuser"];
$dbtype = (! empty($HTTP_POST_VARS["dbtype"])) ? $HTTP_POST_VARS["dbtype"]
    : (function_exists("mssql_connect") ? "mssql" : "mysql");
$targetType = (! empty($HTTP_POST_VARS["targetType"]))
     ? $HTTP_POST_VARS["targetType"] : $dbtype;


Woher die HTTP_POST_VARS kommen sollen, war mir unklar daher habe ich das wie folgt
angepasst.

CODE:
$dbpasswd ='pass';
$dbhost = 'localhost';
$dbname = 'db123';
$dbuser = 'user123';
$dbtype = 'mssql';
$targetType = 'mysql';


Nun kann man das Skript über den Browser aufrufen und erhält die Datei direkt zum
Download. Ist dies nicht der Fall fehlt vermutlich PEAR::DB, welches unbedingt vorhanden
sein muss.

Dies kann man allerdings auch direkt in das Verzeichnis hochladen, wenn PEAR nicht
direkt gegeben ist. Auf dies komme ich in einem der nächsten Blog Einträge zurück.

Posted by Peter Rehm

03/19/2007 at 09:19:21 AM

Posted in Programmierung

Defined tags for this entry: , ,

FCK Editor 2.4 und das Phänomen der kleingeschriebenen Pfade

without Comments

Seit der Einführung von FCK Edit 2.4 wurde ein kleines Detail verändert.
Bisher hat der Editor die Dateien die man hochgeladen hat, immer in
/userfiles/Image/ oder z.b. /userfiles/File/ hochgeladen
Image oder File sind die Ressource Typen.

Seit 2.4 lädt der Editor aber die Dateien immer in /userfiles/image/.
Das ist ziemlich blöd, wenn der Kunde alle seine Bilder in /Image/ liegen hat.
Dazu gibt es 2 Lösungsansätze.

1.) Umbenennen von /Image/ in /image/

Das alte Verzeichnis kann einfach in kleingeschrieben umbenannt werden.
Dies sollte man mit allen Ressource Typen machen, die man verwendet.
Allerdings sollte man beachten, dass man evtl. noch eine Datenbank updaten
muss, wenn sich die Pfade geänder haben.

Dies kann man mit der Anleitung des vorherigen Blog Posts machen.

2.) Man passt die PHP Datein vom FCKEditor an

Seit der neuen Version hat sich hier was verändert

CODE:
editor/filemanager/browser/default/connectors/php/io.php:34:               
   return $GLOBALS["UserFilesPath"] . strtolower( $resourceType ) . $folderPath ;
editor/filemanager/browser/default/connectors/php/io.php:45:       
   $sResourceTypePath = $GLOBALS["UserFilesDirectory"] . strtolower( $resourceType ) . '/' ;


Und zwar ist das strtolower hinzugekommen. Entfernt man dieses verhält sich alles wieder wie gehabt.

CODE:
editor/filemanager/browser/default/connectors/php/io.php:34:               
   return $GLOBALS["UserFilesPath"] . $resourceType  . $folderPath ;
editor/filemanager/browser/default/connectors/php/io.php:45:       
   $sResourceTypePath = $GLOBALS["UserFilesDirectory"] . $resourceType . '/' ;


Zusammenfassung
Allerdings ist die Methode 1 sicher die zukunftssichere. Da man sonst bei jedem Update wieder an das ändern der
Dateien denken muss.


Posted by Peter Rehm

03/18/2007 at 10:37:16 AM

Posted in Programmierung

Defined tags for this entry: ,

Validierung von Ausweisdaten mit PHP

without Comments

Es kursieren unzählige Mythen um die Ausweisnummer. So behaupten einige,
die letzte Ziffer, sei die Zahl, wieviele Leute in Deutschland einem ähnlich
sind :-)
Dem ist nicht so. Hinter der Ausweisnummer steckt ein triviales System.

Der erste Block setzt sich zusammen aus der Ausgabenummer des Ortes, von dem
man den Ausweis bezogen hat, einer zufälligen Nummer, einer Prüfziffer, und
der Staatsangehörigkeit.

Beispiel:

CODE:
0000000005D


Die letzte Zahl vor dem D ist die Prüfziffer (5), und das D ist die Staatsangehörigkeit,
also Deutsch.

Der zweite Block beinhaltet das Geburtsdatum des Ausweisinhabers, in der
Form YYMMDD und eine Prüfziffer

Beispiel:

CODE:
8607209


9 ist in dem Beispiel die Prüfziffer, und der Ausweisinhaber wurde am 20. Juli 1986
geboren.

Der dritte Block ist wie der zweite, beinhaltet allerdings das Gültigkeitsdatum.

Beispiel:
CODE:
8607209


In dem Fall ist die Prüfziffer wieder 9, und der Ausweis ist gültig bis zum 20. Juli 1986.

Der letzte Block ist eine Prüfziffer von den Prüfziffern.

Prüfziffern



Hinter den Prüfziffern verbirgt sich ein einfacher Algorithmus.

CODE:
7 * die erste Zahl + 3 * die zweite Zahl + die dritte Zahl + 7 * die erste Zahl,...


Dies wird solange wiederholt, bis alle Zahlen summiert werden. Das Ergebnis Modulo 10
ist dann die Prüfziffer.

Beispiel:
CODE:
8607209


Berechnung:
CODE:
8*7 + 6*3 + 0 + 7*7 + 2*3 + 0 = 129

129 % 10 = 9

Daher ist die Prüfziffer 9.


Auch die Prüfziffer der Prüfziffern wird nach dem gleichen Algorithmus berechnet.

Code



CODE:
<?php
/**
* class to verify the german passport number
*/
class verify_passport
{

var $full_number;
var $blocks=array();
var $result;
var $is_valid=true;
var $expires;

/**
* Constructor
* @param string $number passportnumber
* @return void
*/
function verify_passport($number)
{
/**
* Remove the < and split into the 4 blocks
* If $number > 26 $number is invalid
*/
if(strlen($number)>26 || strlen($number)<26)
{
$number=str_replace('<','',$number);
if(strlen($number)>26)
{
die('invalid passport length');
}
}

$this->blocks[1]=substr($number,0,11);
$this->blocks[2]=substr($number,11,7);
$this->blocks[3]=substr($number,18,7);
$this->blocks[4]=substr($number,25,1);
foreach($this->blocks as $key => $value)
{
if(!$this->verify_block($key,$value))
{
echo $key;
$this->is_valid=false;
return;
}
}

/**
* Set the expire date
*/
$this->expires=mktime(0,0,0,substr($this->blocks[3],2,2),substr($this->blocks[3],4,2),substr($this->blocks[3],0,2));

}

/**
* Verifies the single Blocks
* @param integer $type block id
* @param string $data block content
* @return boolean
*/
function verify_block($type,$data)
{
switch($type)
{
case 1:
return ($this->calc_checksum(substr($data,0,-2))==$data{9} ? true : false );
break;
case 2:
case 3:
return ($this->calc_checksum(substr($data,0,-1))==$data{6} ? true : false );
break;
case 4:
return ($this->calc_checksum(substr($this->blocks[1],0,-1).substr($this->blocks[2],0).substr($this->blocks[3],0))==$data{0} ? true : false );
break;
}
}

/**
* Calculates the Checksum for the given line
* @param string $data
* @result unit place of the checksum
*/
function calc_checksum($data)
{
$result=0;
$length=strlen($data);
for($i=0;$i<$length;$i++)
{
switch($i%3)
{
case 0:
$result+=$data{$i}*7;
break;
case 1:
$result+=$data{$i}*3;
break;
case 2:
$result+=$data{$i};
break;
}
}
return $result%10;
}

/**
* Checks if all was valid - Also if passport is not expired
* @return boolean
*/
function is_valid()
{
if($this->is_valid)
{
if(time()<=$this->expires)
{
return true;
}
}
return false;
}

/**
* Returns the Age in array or unix timestamp
* @param integer $type 0=array 1=timestamp
* @return array or timestamp
*/
function get_age($type='0')
{

$year=substr($this->blocks[2],0,2);
/*
* Create a 4 digit Year number
*/
if($year>=20)
{
$year=(substr(date("Y"),0,2)-1)*100+$year;
} else {
$year=substr(date("Y"),0,2)*100+$year;
}
$month=substr($this->blocks[2],2,2);
$day=substr($this->blocks[2],4,2);

if($type==0)
{
return array('year'=>$year,
 'month'=>$month,
 'day'=>$day);
} else {
return mktime(0,0,0,$month,$day,$year);
}
}
}
?>


Funktionsweise


Der Constructor teilt die Nummer in die Blocks auf, und überprüft ob die Länge
der Nummer korrekt ist. Ist dies nicht der Fall wird die Class sofort beendet.
Der die() ist zugegeben etwas hart, und sollte im Produktiven Einsatz vielleicht
nicht so verwendet werden :-)

Danach kann ich mir über die Methode is_valid() anzeigen lassen, ob die
Ausweisnummer gültig ist. Die Funktion gibt einen Boolschen Wert zurück.
Neben den Prüfziffern wird auch überprüft, ob das Ablaufdatum noch nicht
erreicht ist.

Man kann sich auch das Geburtsdatum als Unix Timestamp oder als Array ausgeben lassen.
Dies geht mittels get_age($type). ist type 0 wird in Array mit den Keys (year,month,day
zurückgegeben, ansonsten ein Unix Timestam.

Der Einsatz



Das folgende Beispiel soll abschließend die Funktionsweise verdeutlichen.

CODE:
$try=new verify_passport($ppn);
var_dump( date("Ymd",$try->get_age(1)) );
var_dump( $try->is_valid() );


$ppn sollte die Ausweisnummer beinhalten.

Posted by Peter Rehm

03/05/2007 at 06:51:31 PM

Posted in PHP

Defined tags for this entry: ,

Mails UTF-8 kodiert versenden

without Comments

Ergänzend zum dem Eintrag bezüglich UTF-8 in Webapplikationen hier noch eine kurze Info zum versenden von UTF8 Mails mit PHP.

Man kann zum einen die Mails wieder in ISO konvertieren, allerdings möchte ich nur auf die Möglichkeit eingehen,
Mails unkonvertiert zu versenden. Dazu muss an sich nur das Encoding im Header in der Funktion mail()
gesetzt werden.

CODE:
mail("reciever@reciever.de",
 "subject",
 "content",
 "From: bla@bla.de\r\nContent-Type: text/plain; charset=UTF-8");


Alternativ kann man auch mb_send_mail() verwenden.

Posted by Peter Rehm

02/17/2007 at 06:04:50 PM

Posted in PHP

Defined tags for this entry: ,

CSV Dateien in MySQL importieren

without Comments

Ich musste gerade eine Reihe Postleitzahlen importieren, daher habe ich eine Quick & Dirty Lösumg geschrieben um CSV Dateien zu importieren.

CODE:
<?php

class csv2mysql
{
/**
* DB Host
*/
var $host='';

/**
* DB User
*/
var $user='root';

/**
* DB Pass
*/
var $pass='';

/**
* DB Name
*/
var $db;

/**
* Table Name
*/
var $table;

/**
* CSV Separator
*/
var $separator=';';

/**
* Filename to import
*/
var $filename;

/**
* DB Handle
*/
var $db_handle;

/**
* File Handle
*/
var $file_handle;

/**
* Max Line length in CSV File
*/
var $max_line_length=1000;

/**
* Insert Count
*/
var $count=0;

/**
* Konstruktor to set the options
*
* options: dbname,tablename,separator
*/
function csv2mysql($options)
{
if(empty($options['dbname']))
{
die("you have to enter a database name!");
} else {
$this->db=$options['dbname'];
}

if(empty($options['table']))
{
die("you have to enter a table name!");
} else {
$this->table=$options['table'];
}

if(empty($options['filename']))
{
die("you have to enter a filename!");
} else {
$this->filename=$options['filename'];
if(!file_exists($this->filename))
{
die("file does not exist");
}
}

if(!empty($options['separator']))
{
$this->separator=$options['separator'];
}

$this->db_handle=mysql_connect($this->host,$this->user,$this->pass);
mysql_select_db($this->db,$this->db_handle);

return;
}

function convert()
{
$this->file_handle=fopen($this->filename,"r");
if($this->file_handle && $this->db_handle)
{
while($data=fgetcsv($this->file_handle,$this->max_line_length,$this->separator))
{
$res=mysql_query("INSERT INTO ".$this->table."
 VALUES (".join($data,',').")",$this->db_handle) or die(mysql_error());
if($res)
{
$this->count++;
}
}
echo $this->count;
} else {
die("could not open file or database");
}
}
}

$imp=new csv2mysql(array('filename'=>'/www/test.csv',
'dbname'=>'plzdb',
'table'=>'plz'));
$imp->convert();
?>


Aufgrund den anstehenden Prüfungen verzichte ich auf das erklären des Codes, das müsste man auch so verstehen können :-)

Posted by Peter Rehm

01/18/2007 at 09:33:35 PM

Posted in PHP

Defined tags for this entry: , , ,

Arrays in Smarty

without Comments

In Smarty Templates kann man, welch wunder, auch auf Arrays zugreifen.

CODE:
{$array.element1}


Dies stellt die einfachste Art dar, wie man dies erledigen kann. Mit der ist man wohl
auch desöfteren konfrontiert, und stellt daher bestimmt kein Problem dar.

Allerdings kann Smarty auch mit [] umgehen, und ermöglicht daher auch den dynamischen
Zugriff auf mehrdimensionale Arrays.

CODE:
{foreach item=car from=$data}
          <th>{$calc[$car.sxID].20000.total_saving}</th>
{/foreach}


Dies ist für manche Anwendungsfälle ganz praktisch.

Posted by Peter Rehm

12/31/2006 at 12:27:41 AM

Posted in PHP

Defined tags for this entry: , ,

PHP4 und PHP5 auf einem Confixx Server

without Comments

Ich hab eine Anleitung gefunden, die das möglich macht. Getestet habe ich das nicht, da ich zum Glück keinen Confixx Server mehr verwalten muss.

Allerdings ist das sicher für einige interessant, ich wäre auch froh, wenn das mein Provider endlich umsetzen würde :-)

http://www.mytso.net/howtos/suphp-confixx3-php4-php5

Posted by Peter Rehm

12/30/2006 at 05:51:14 PM

Posted in Verschiedenes

Defined tags for this entry: ,