Wikileaks @ xkcd
Oktober 10th, 2011
PHP script for validating a XML file against a XSD Schema
Oktober 10th, 2011
usage: php validate-xsd.php xmlfile xsdfile validates xmlfile against xsdfile
#!/usr/bin/php <?php if($argc !== 3) { echo "usage: ". $argv[0] . " xmlfile xsdfile\n"; echo "validates xmlfile against xsdfile\n"; die(); } if(!is_readable($argv[1])){ die("cannot read xmlfile '{$argv[1]}'. aborting.\n"); } if(!is_readable($argv[1])){ die("cannot read xsdfile '{$argv[2]}'. aborting.\n"); } $xmlfile = $argv[1]; $xsdfile = $argv[2]; echo "validating $xmlfile against $xsdfile\n"; libxml_use_internal_errors(true); $feed = new DOMDocument(); $feed->preserveWhitespace = false; $result = $feed->load($xmlfile); if($result === TRUE) { echo "Document is well formed\n"; } else { echo "Document is not well formed\n"; } if(@($feed->schemaValidate($xsdfile))) { echo "+ Document is valid!\n"; } else { echo "! Document is not valid:\n"; // var_dump the error messages $errors = libxml_get_errors(); foreach($errors as $error) { echo "---\n"; printf("Error: %s \nfile: %s, line: %s, column: %s, level: %s, code: %s\n", $error->message, $error->file, $error->line, $error->column, $error->level, $error->code ); } }
printf like log function for PHP
Oktober 9th, 2011
The following functions are good friends for logging. You can use format strings parsed by printf and several log levels.
Usage example : ( Download: example.php)
<?php /** * Require l.php before parsing the ini file * so that L_* contants can be used in the ini file * to define the L_LEVEL */ require_once 'l.php'; $config = parse_ini_file('config.ini'); define('l_reporting', intval($config['l_reporting'])); l ('test', L_NOTICE); l (1); l (3.4); l (FALSE); l (NULL, L_DEPRECATED); l (array(1,2,3)); l (new DOMDocument()); lf ('file: %s', @file_get_contents('sada'), L_ERROR); lf ('hello %s! The time is %s', 'thorsten', date('Y:m:i')); lf ('%s in binary is %1$032b', rand());
Assuming this config file:
;... l_reporting = L_ALL; ;...
The output will look like
[2011:10:03][L_NOTICE] test [2011:10:03][L_ERROR] file: FALSE
When using the following config file:
; ... l_reporting = L_VDEBUG; ; ...
Then the output will look like:
[2011:10:29]test [2011:10:29]1 [2011:10:29]3.4 [2011:10:29]FALSE [2011:10:29]Array ( [0] => 1 [1] => 2 [2] => 3 ) [2011:10:29]DOMDocument Object ( ) [2011:10:29]file: FALSE [2011:10:29]hello thorsten! The time is 2011:10:29 [2011:10:29]1296685703 in binary is 01001101010010011101101010000111
<?php /** * Printf like log function for php * * @example /** * Parse current log level from ini file. If doing * is AFTER define('L_*', ..) contants, one can use * this constants in the ini file. * * Example ini file: * ... * l_reporting = E_ALL | DEBUG; * ... *\/ * $config = parse_ini_file('config.ini'); * define('L_LEVEL', intval($config['l_reporting'])); * * l ('test', L_NOTICE); * l (1); * l (3.4,); * l (FALSE); * l (NULL, L_DEPRECATED); * l (array()); * l (new DOMDocument()); * lf ('file: %s', @file_get_contents('sada'), L_ERROR); * lf ('hello %s! The time is %s', $argv[1], new DateTime()); * lf ('SOME_INT_VALUE is %1$016b %1$s', SOME_INT_VALUE); * * @author Thorsten Heymann <info@metashock.net> */ /** * Common log levels * define them before parsing the ini file */ define('L_ERROR', 1); define('L_WARNING', 2); define('L_NOTICE', 4); define('L_ALL', L_ERROR | L_WARNING | L_NOTICE); define('L_DEBUG', 8 | L_ALL); define('L_VDEBUG', 16 | L_DEBUG); define('L_DEPRECATED', 32); /** * Custom log levels are after bit 8 */ define('L_MODEL_DEBUG', 256); /** * A log function like printf. * * For the flexibiltity that $level is an optional parameter, * we have to pay the the price of "must parse the fmt string" * to find out how many arguments in arglist are used as fmt args, * and then detect if the log level was was specifed and get its value. * So try to use this method with $fmt strings as short as possible * to avoid overhead. * * l($mixed [, $level = L_DEBUG]); * l($fmt_str, $fmt_arg0, ..., $fmt_arg [, $level = L_DEBUG]); * * @return string | FALSE */ function lf ($message /* , $args ..., $level = L_DEBUG*/) { // get number of arguments $nargs = func_num_args(); if($nargs < 1) { user_error(sprintf('%s expected at least one argument')); return FALSE; } $nfmtargs = 0; // check if first argument is a string if ( is_string ( func_get_arg (0) )) { // then check how much format arguments // the string consumes $fmt = func_get_arg(0); $args = array(); for($i = 0; $i < strlen($fmt); $i++) { if($fmt[$i] !== '%') { continue; } $argindex = ''; while(ord($fmt[$i+1]) > 0x29 && ord($fmt[$i+1]) < 0x40) { $argindex .= $fmt[$i+1]; $i++; } if($argindex === '' || $fmt[$i+1] !== '$' ) { $nfmtargs++; } else if (!isset($args[$argindex])) { $nfmtargs++; $args[$argindex] = TRUE; } } } // $level is the last argument in list // if $level was not set we assume L_DEBUG as the default value if($nargs < $nfmtargs + 2) { $level = L_DEBUG; } else { $level = func_get_arg($nargs -1); } $printfargs = array(); // check if there are arguments to the ftm string for($i = 0; $i < max(1, $nargs); $i++) { $arg = func_get_arg($i); // convert none printf arguments to printf arguments. // if they are willing or not! if(is_string($arg) || is_float($arg) || is_int($arg) || (is_object($arg) && method_exists($arg, '__toString')) ) { $printfargs []= $arg; } else if(is_bool($arg)) { $printfargs []= $arg ? 'TRUE' : 'FALSE'; } else if(is_null($arg)) { $printfargs []= 'NULL'; } else { $printfargs []= print_r($arg, TRUE); } } // call printf $msg = call_user_func_array ('sprintf', $printfargs); return l($msg, $level); } /** * Logs a message to stderr * * @param mixed $message * @param integer $level=L_DEBUG * @return string the log message */ function l($message, $level = L_DEBUG) { // check if $level passes current L_LEVEL filter if(($level & l_reporting) !== $level) { return ''; } // convert $message to a string - willing or not! if(is_bool($message)) { $message = $message ? 'TRUE' : 'FALSE'; } else if(is_null($message)) { $message = 'NULL'; } else if(is_object($message) || is_array($message)) { $message = print_r($message, TRUE); } $prefix = '[' . date('Y:m:i') . '][' . l_reporting_to_string($level) . '] '; $message = $prefix . $message; // just using STDERR here. Use your own logger .. fwrite(STDERR, $message . PHP_EOL); return $message . PHP_EOL; } /** * Gives a string representation of the common * log levels * * @param integer * @return string */ function l_reporting_to_string($level) { $switches = array(); if(($level & L_ERROR) === L_ERROR) { $switches []= 'L_ERROR'; } if(($level & L_WARNING) === L_WARNING) { $switches []= 'L_WARNING'; } if(($level & L_NOTICE) === L_NOTICE) { $switches []= 'L_NOTICE'; } if(($level & L_DEBUG) === L_DEBUG) { $switches []= 'L_DEBUG'; } if(($level & L_VDEBUG) === L_VDEBUG) { $switches []= 'L_VDEBUG'; } if(($level & L_DEPRECATED) === L_DEPRECATED) { $switches []= 'L_DEPRECATED'; } return implode(' | ', $switches); }
Play around with various combinations of l_reporting levels. (And report bugs
)
Hexdump function in PHP
April 30th, 2011
This goodie comes with her little friend – asciidump().
Have fun!
/** * Prints a hexdump of $data * * @param string $data * @param integer $ncolumns = 8 * @return void * @throws InvalidArgumentException if one of the arguments data type mismatches * @throws OutOfBoundsException if $ncolumns is lower than 0 */ function hexdump($data, $ncolumns = 8) { // check arguments if (!is_string($data)){ throw new InvalidArgumentException ( '$data expected to be string. <' . gettype($data) . '> found.'); } if (!is_int($ncolumns)){ throw new InvalidArgumentException ( '$ncolumns expected to be integer. <' . gettype($ncolumns) . '> found.'); } if($ncolumns < 1) { throw new OutOfBoundsException ( '$columns expected to be a positve integer. <' . $ncolumns . '> found.'); } for($i = 0; $i < strlen($data); $i++){ printf('0x%02x ', ord($data[$i])); $c = $i % $ncolumns; if($c === $ncolumns - 1) { // after n hex chars we print the ascii dump for($ii = $i - $c; $ii < $i + 1; $ii++) { asciidump($data[$ii]); } } } // if the last line has no exactly $ncolumn chars // we insert padding chars before the last ascii chars $rest = $ncolumns - ($i % $ncolumns); if($rest !== $ncolumns) { for($ii = 0; $ii < $rest; $ii++){ print(' '); } for($ii = $i - ($ncolumns - $rest); $ii < $i; $ii++){ asciidump($data[$ii]); } } print(PHP_EOL); } /** * Prints $data. Non printable chars will be converted * to $placeholder * * @param string $data * @param string $placeholder='.' * @return void */ function asciidump($data, $placeholder = '.') { // check arguments if (!is_string($data)){ throw new InvalidArgumentException( '$data expected to be array or string. ' . gettype($data) . ' found.'); } for($i = 0; $i < strlen($data); $i++) { // is this an ascii character ? if(ord($data[$i]) > 31 && ord($data[$i]) < 127) { print($data[$i]); } else { print($placeholder); } } }
Clone a VirtualBox Hard Disk
April 20th, 2011
When working with VirtualBox, sometimes its useful to clone a OS by just duplicate the *.vdi hard disk file and create a new OS with this hard drive. When you just copy and paste the .vdi file you’ll get an error because the uuids of the partions on the already in use by VirtualBox. The correct way to do this is:
on Windows:
%VIRTUAL_BOX_DIR%/VBoxManage.exe clonevdi ORIGINAL_FILE CLONE
