4
Jan

Prüfziffer der ISIN in PHP

categories Computer, PHP    

Die ISIN (International Securities Identification Number) ist eine Kennung für Wertpapiere. Wie viele andere solcher Kennungen, beinhaltet auch die ISIN ein Prüfziffer-Verfahren. Wie das in Theorie funktioniert, hat jemand richtig gut bei Wikipedia beschrieben.

Hiermit zeige ich eine kleine Klasse, wie man das in PHP machen kann (use with care and at own risk!). Ursprünglich hatte ich diesen Code in 2010 veröffentlicht, in 2018 arbeitete ich die Hinweise einiger Nutzer ein und aktualisierte die Routinen zu PHP7.

declare(strict_types=1);

/**
 * Validierung einer ISIN (double at double-method)
 * 2010-2018 von Björn A. Dietz
 */
class isin_validate{
	public $isin;
	private $cvok;

	function __construct($isin = false) {
		if ($isin) $this->isin = $isin;
	}

	public function isin_check() {
		$isin = strtoupper($this->isin);
		$s=""; $cv = 0;
		$this->cvok = false;

		for ($i=0;$i<=10; $i++) {
			$b = substr($isin,$i,1);
			if (ord($b)>=65 && ord($b)<=90) $b = ord($b)-55;
			$s .= $b;
		}

		$s = strrev($s);

		for ($i= 0;$i<=strlen($s);$i++) {
			$b = (int) substr($s,$i,1);
			if (!bcmod((string) $i, "2")) $b = $this->quersumme($b * 2);
			$cv += $b;
		}
		
		$cv = 10 - bcmod((string) $cv, "10");
		$cv = bcmod ((string) $cv, "10");

		if ($cv == substr($isin,-1,1)) $this->cvok = true;
		return $this->cvok;
	}

	private function quersumme($zahl) {
		$strZahl = (string) $zahl;
		for( $intQS = $i = 0; $i < strlen ($strZahl); $i++ ) {
			$intQS += (int) $strZahl{$i};
		}
		return (int) $intQS;
	}
}

…und so kann man die Klasse verwenden:

/* Anwendungsbeispiel */
$cv_test = new isin_validate("DE000BAY0017");
echo $cv_test->isin_check();

Ich weiß, das geht immer noch besser… so ist es aber schön übersichtlich!

13
Feb

50 Shades of Grey

categories Aktuelles, Computer, PHP    

Well, everybody’s talking about it, don’t they? 🙂

header("Content-type: image/png");
$head = "50 Shades of Grey";
$im = imagecreate(500,280);
$background_color = imagecolorallocate($im, 0, 0, 0);

$orange = imagecolorallocate($im, 220, 210, 60);
$px = (imagesx($im) - 7.5 * strlen($head)) / 2;
imagestring($im, 3, $px, 9, $head, $orange);

$colc = 5;

for ($i = 0; $i < 500; $i = $i + 50) {
    for ($j = 29; $j < 250; $j = $j + 50) {
        $col = imagecolorallocate($im, $colc, $colc, $colc);
        imagefilledrectangle($im, $i+1, $j+1, $i+49, $j+49, $col);
               
        $coln = str_pad(dechex($colc), 2, "0", STR_PAD_LEFT);
        imagestring($im, 2, $i+2, $j+2, "#".$coln.$coln.$coln, $orange);
        $colc += 5;
    }
} 

imagepng($im);
imagedestroy($im); 

23
Mar

Unittests with PHPUnit

categories Computer, PHP, Tutorials    

A little private encounter with the community of an open source project opened my eyes, how good and easy life as a coder is if you’re working with unit tests. Not everybody uses them, but everybody should. For php programming the ideal software for this is PHPUnit.

The software can be obtained from GitHub verteilt, is well documented, widely used and very popular. It is also in the PEAR project and can be installed using the PEAR installer (it has some dependencies for additional features).

To demonstrate the basic procedural manner I’ll use a simple example. Imagine… somewhere within a php project there is a function, which returns easter sunday given any year. To make things easy, we’ll name it easter($year). Such a function could be used for determining holidays and therefore could have a certain criticality. How can this be tested with PHPUnit?

Let’s delve into code:

require_once 'includes/functions.php';
 
class EasterTest extends PHPUnit_Framework_TestCase {
  public function testEasterOk() {
    $easter2011 = easter(2011);
    $this->assertEquals($easter2011, gmmktime(0,0,0,4,24,2011));
  }
 
  public function testEasterFalse() {
    $easter2011 = easter(2011);
    $this->assertNotEquals($easter2011, gmmktime(0,0,0,12,24,2011));
  }
} 

First there is a link to the script containing the easter-function (here: functions.php). Then I generate a new class (“EasterTest”), which extends PHPUnit. In this class there are two basic tests:

Now to the boring theoretical part…
The solution isn’t the aim here – one glance at a calender should help you way better. The goal is, to compare the functions result with a defined result. I know for sure, that this years easter sunday is on 24.04. (as long as my calendar isn’t lying!) … und I know for sure, 24.12. ain’t somewhere near easter.

PHPUnit – like many other software products around unit testing – works with “assertions”. There is a library of simple functions for assertions in different constructs – for comparisms (like the here used assertEquals and assertNotEquals), arrays, bools and so on.

How much work is it?
Please decide for yourself. An easy test should be coded within less than five minutes. Not too difficult, ain’t it?

Back to work.

How can you now run those tests? Easiest way: use your shell (whatever, either Dos, Bash or anything else php runs on).

D:\htdocs\>phpunit EasterTest.php
PHPUnit 3.5.11 by Sebastian Bergmann.

..
 
Time: 0 seconds, Memory: 3.75Mb
 
OK (2 tests, 2 assertions)

PHPUnit can express itself using different output formats, for example TAP (“Test Anything Protocol”), JSON, XML and some more.

D:\htdocs\>phpunit --tap EasterTest.php
TAP version 13
ok 1 - EasterTest::testEasterOk
ok 2 - EasterTest::testEasterFalse
1..2

Now… how does it look like if there is an error? To test this I slighly changed my first test and assumed, 23.04.2011 is easter sunday – in reality it is the saturday.

D:\htdocs\>phpunit --tap EasterTest.php
TAP version 13
not ok 1 - Failure: EasterTest::testEasterOk
  ---
  message: 'Failed asserting that <integer:1303516800> matches expected <integer:1303603200>.'
  severity: fail
  data:
    got: 1303516800
    expected: 1303603200
  ...
ok 2 - EasterTest::testEasterFalse
1..2

If I return coding on the easter-function in the far future, then I still have my unit tests and can run them whenever I like (or whenever I need!). If the tests then return errors, either my tests are wrong or my function is (guess what is more likely). And this is what this is all about. Unit testing makes your code stronger and additions much easier.

And…if you encounter bugs… just write a test first and then fix it!

5
Mar

PHP-Commandline-Parameter with Console_Getopt

categories PHP, Tutorials    

Mainly due to historical reasons my guess is most developers are using php as a language to build web pages and web applications. PHP can do alot more: it has a commandline interface, which enables you to write scripts using several different enviroments.

Parameters are stored in a special variable $argv.

Example 1: test_argv.php

<?php
var_dump($argv);
?>

Output Example 1:

d:\php5> php.exe test_argv.php IchBinParam1 UndIch2
array(3) {
  [0]=>
  string(13) "test_argv.php"
  [1]=>
  string(12) "IchBinParam1"
  [2]=>
  string(7) "UndIch2"
}

Not too bad so far. If you now want to start parsing and checking parameters, such a structure can easily get complicated. To make things easier, there is a little class called Console_Getopt in the PEAR project.

Installation
If you’re using PEAR, simply use the pear installer.

d:\php5> pear install Console_Getopt-1.3.0

But you don’t have to. It is sufficent to download the class here and include it into your project.

Usage
Not only installing this class is easy, so is the usage of it. Just include the class into your programm, initialize the class object, define allowed options and then check the parameters.

Here’s a simple example.

Beispiel 2: demo_getopt.php

<?php
// include class
include ("Getopt.php");

// initialize class
$cg = new Console_Getopt();

/** 
 * allowed options:
 * -a Abba
 * -b Beatles
 * -q Queen
 */
$allowedOptions = "abq";

// read commandline
$args = $cg->readPHPArgv();

// filter options
$ret = $cg->getopt($args, $allowedOptions);

// error message
if (PEAR::isError($ret)) {
    die ("error in commandline: " . $ret->getMessage() . "\n");
}

// print the options
print_r($ret);
?> 

Output Example 2:

d:\temp\getopt>php.exe demo_getopt.php -ab Who Genesis
Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => a
                    [1] =>
                )

            [1] => Array
                (
                    [0] => b
                    [1] =>
                )

        )

    [1] => Array
        (
            [0] => Who
            [1] => Genesis
        )

)

d:\temp\getopt>d:\php5\php.exe demo_getopt.php -c
Error in command line: Console_Getopt: unrecognized option -- c

After filtering the options you can now retrieve the command line parameters and work with them.

Example 3: demo_getopt_erweitert.php

.
.
.
// filter options
$ret = $cg->getopt($args, $allowedOptions);

$optionen = $ret[0];
if (sizeof($optionen) > 0) {
    // at least one option has been used
    foreach ($optionen as $o) {
        switch ($o[0]) {
            case 'a':
                echo "you choose: Abba\n"; 
                break;
            case 'b':
                echo "you choose: Beatles\n"; 
                break;
            case 'q':
                echo "you choose: Queen\n"; 
                break;
        }
    }
} 

The class can do a few things more, for example it is possible to check for optional or necessary parameters, check for strings or numeric values and things like this.

If you want to take a closer look into the class, it is well documented. A more detailed article with a few more examples can be found here at Zend.

18
Mar

Installation einer XAMP-Umgebung

categories MySQL, PHP, Tutorials    

Aufgrund eines neuen Rechners kam ich mal wieder in die Verlegenheit, meine private Entwicklungsumgebung neu einzurichten. Die üblichen Entwickler-Suites (z.B. Visual Studio 2005, UltraEdit, PHPEdit u.v.m.) sind via Setup zügig installiert. Ich möchte jedoch noch lokal – d.h. unter WinXP (prof.) – einen kleinen HTTP-Server bedienen, mit welchem ich später datenbanklastige PHP-Skripte kreieren und testen kann.

Plan A: Download von XAMPP für Windows.
Plan B: Selbermachen!

Ich stimme für Plan B – dabei lernt man üblicherweise am meisten über die verwendeten Systeme. Was benötige ich dafür?

(more…)

Next Page →