php snippets

PHP XML-RPC example using Pear's XML_RPC package

Tagged php, pear, xml-rpc  Languages php

First you need to install XML_RPC and VAR_DUMP:

Installing XML_RPC

pear install XML_RPC
pear install VAR_DUMP

Example XML-RPC client

Note this code hasn't been tested, so may contain errors.

Anyway, VAR_DUMP is great for debugging...

<?php
  require_once("XML/RPC.php");
  require_once('Var_Dump.php');

  Var_Dump::displayInit(array('display_mode' => 'HTML4_Text'), array('mode' => 'normal','offset' => 4));
  
  $host = "xxx.com";
  $uri = "/xxx/xmlrpc";

  $function   = "eat";
  $parameters = array(
    new XML_RPC_Value("a"),
    new XML_RPC_Value(0),
    new XML_RPC_Value(10),
    new XML_RPC_Value("b")
  );
  
  $message = new XML_RPC_Message($function, $parameters);
    
  $client = new XML_RPC_Client($uri, $host, 80);
  $client->setDebug(1);
  $client->proxy = "127.0.0.1";

  $result = $client->send($message);

  if (!$result) {
    echo 'Communication error: '.$client->errstr;
    Var_Dump::display($client);
    exit;
  }

  if($result->faultCode())
  {
     echo "** ERROR **n";
     echo 'Fault Code: ' . $result->faultCode() . "n";
     echo 'Fault Reason: ' . $result->faultString() . "n";
     exit;
  }

  echo "<pre>".htmlentities($message->serialize()). "</pre>";

  Var_Dump::display($result);

  $val = $result->value();
  $ticket = $val->scalarval();
  
  echo $ticket;
?>

Data types

struct

$user_params =  array(
    'username'       => new XML_RPC_Value(".."),
    'email'          => new XML_RPC_Value("..."),
    'time'  => new XML_RPC_Value(gmdate("Ymd\TH:i:s"), 'dateTime.iso8601')
    );

$rpc_param = new XML_RPC_Value($user_params, 'struct')

dateTime.iso8601

'time'  => new XML_RPC_Value(gmdate("Ymd\TH:i:s"), 'dateTime.iso8601')

How to upload a file with PHP and lib_curl

Tagged php, file, upload, client, pear  Languages php

This is an example of how to upload a file from PHP to another server that may or may not be running PHP.

Note that using Pear's HTTP_Request package is probably easier.

<?php
  require_once('Var_Dump.php');
  Var_Dump::displayInit(array('display_mode' => 'HTML4_Text'), array('mode' => 'normal','offset' => 4));

  $url = 'www.aktagon.com/upload';
  $file = '/tmp/file_to_upload';
  $post_data = array();

  $post_data['username'] = '';
  $post_data['password'] = '';
  $post_data['file'] = "@$file";

  $ch = curl_init();

  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array(
#    'Cookie: xxxx',
#    'Content-Type: xxxx'
  ));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  curl_setopt($ch, CURLOPT_POST, true);
  #curl_setopt($ch, CURLOPT_PROXY, '127.0.0.1:8888');

  curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);

  $response  = curl_exec($ch);
  $info      = curl_getinfo($ch); 
  $http_code = $info['http_code'];
  $speed     = round($info['speed_upload'] / 1024);
  $size      = round($info['size_upload'] / 1024);

  if($http_code != 200)
  {
    echo "Upload failed with HTTP code $http_code. Uploaded $size kilobytes with $speed kilobytes/s.<br/>";
    echo "<h1>Response</h1><pre>$response</pre><h1>Debug information</h1>";

    Var_Dump::display($info);
  }
  else
  {
    echo "Uploaded successful. Uploaded $size kilobytes with $speed kilobytes / s.<br/>";
    echo "<h1>Response</h1><pre>$response</pre>";
  }
  curl_close($ch);
?>

You can remove the Var_Dump code (Pear module), if you haven't installed it, or don't need it.

A simple HTTP client for PHP

Tagged http, client, php  Languages php

A simple HTTP client for PHP that uses curl:

class HTTP {
    static function get($url, $headers=null) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_HEADER, true);

        if($headers) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }

        // Execute request
        $response = curl_exec($ch);

        // Split headers and body
        list($header_text, $body) = explode("\r\n\r\n", $response, 2);
        $header_lines = explode("\r\n", $header_text);

        // Extract HTTP status
        $header_line = array_shift($header_lines);
        if (preg_match('@^HTTP/[0-9]\.[0-9] ([0-9]{3})@', $header_line, $matches)) {
            $status = $matches[1];
        }

        // Extract HTTP headers
        $headers = array();
        foreach ($header_lines as $header_line) {
            list($header, $value) = explode(': ', $header_line, 2);
            $headers[$header] = $value;
        }

        $info = curl_getinfo($ch); 

        curl_close($ch);    

        $status = $info['http_code'];

        return new Response($status, $body, $headers, $info);
    }
}

Even supports reading response headers.

class Response  {
    public function Response($code, $body, $headers, $info=null) {
        $this->code = $code;
        $this->body = $body;
        $this->headers = $headers;
        $this->info = $info;
    }
}

How to add logging to CakePHP applications

Tagged php, logging, debug, cakephp  Languages php

Note that Pear's Logging package is a lot more flexible, so I recommend you use that instead of CakePHP's built-in logging.

Use this code to add a debug message to the CakePHP debug log:

$this->log("Upload action accessed", LOG_DEBUG);

Note that using something other than LOG_DEBUG will log the message as an error.

Run the code once and you should be able to see the message in $CAKE_APP/tmp/logs/debug.log.

How to print all HTTP headers with PHP

Tagged php, request, headers, http  Languages php
<ul>
 <?php
   foreach($_SERVER as $h=>$v)
     if(ereg('HTTP_(.+)',$h,$hp))
       echo "<li>$h = $v</li>\n";
   header('Content-type: text/html');
  ?>
</ul>

How to format number of seconds as duration with PHP

Tagged seconds, php, duration, format, time  Languages php

A very sophisticated algorithm that will display the length of, for example, a video as 12:01:30.

function duration($seconds_count)
    {
        $delimiter  = ':';
        $seconds = $seconds_count % 60;
        $minutes = floor($seconds_count/60);
        $hours   = floor($seconds_count/3600);

        $seconds = str_pad($seconds, 2, "0", STR_PAD_LEFT);
        $minutes = str_pad($minutes, 2, "0", STR_PAD_LEFT).$delimiter;

        if($hours > 0)
        {
            $hours = str_pad($hours, 2, "0", STR_PAD_LEFT).$delimiter;
        }
        else
        {
            $hours = '';
        }

        return "$hours$minutes$seconds";
    }

How to send both HTML and text emails with PHP and PHPMailer

Tagged php, phpmailer, html, send, email, smtp  Languages php

This is an example on how to use PHPMailer to send an HTML email. It also shows how to include a text only version of the same email for clients, such as mutt, that don't support HTML emails.

$mail = new PHPMailer();

$mail->IsHTML(true);
$mail->CharSet = "text/html; charset=UTF-8;";
$mail->IsSMTP();

$mail->WordWrap = 80;
$mail->Host = "smtp.thehost.com"; 
$mail->SMTPAuth = false;

$mail->From = $from;
$mail->FromName = $from; // First name, last name
$mail->AddAddress($to, "First name last name");
#$mail->AddReplyTo("reply@thehost.com", "Reply to address");

$mail->Subject =  $subject;
$mail->Body =  $htmlMessage; 
$mail->AltBody  =  $textMessage;    # This automatically sets the email to multipart/alternative. This body can be read by mail clients that do not have HTML email capability such as mutt.

if(!$mail->Send())
{
  throw new Exception("Mailer Error: " . $mail->ErrorInfo);
}

How to generate a pronouncable password with PHP

Tagged password, random, php, generate  Languages php

This is a slight modification of a script I found at PHPFAQ:

class Password
{
    static function generate($length)
    {
        srand((double)microtime()*1000000);

        $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);
    }
}

To use it try this code:

require 'password.php'

echo Password.generate(10);

It will spit out passwords that are semi-pronouncable.

PHP file upload gotchas

Tagged gotcha, file, upload, php  Languages php

PHP file upload works in mysterious ways:

http://us3.php.net/manual/en/ini.core.php#ini.post-max-size
http://fi.php.net/manual/en/features.file-upload.php#73762
http://de3.php.net/manual/en/features.file-upload.errors.php

A simple and easy to use PHP XML parser

Tagged php, parser, simple, xml  Languages php

The PHP XML parser:

class XML
{
    static function parse($data, $handler, $encoding = "UTF-8")
    {
        $parser = xml_parser_create($encoding);

        xml_set_object($parser, $handler);
        
        xml_set_element_handler($parser,
            array(&$handler, 'start'),
            array(&$handler, 'end')
        );
            
        xml_set_character_data_handler(
            $parser,
            array($handler, 'content')
        );
            
        $result = xml_parse($parser, $data);

        if(!$result)
        {
            $error_string = xml_error_string(xml_get_error_code($parser));
            $error_line   = xml_get_current_line_number($parser);
            $error_column = xml_get_current_column_number($parser);
            
            $message = sprintf("XML error '%s' at line %d column %d", $error_string, $error_line, $error_column);
            
            throw new Exception($message);
        }

        xml_parser_free($parser);
    }
}

A result handler:

class ResultHandler
{
    var $tag;

    function start ($parser, $tagName, $attributes = null)
    {
        echo "start";
        $this->tag .= $tagName; # Use .= to work around bug...
    }

    function end ($parser, $tagName)
    {
        echo "end";
        $this->tag = null;

    }

    function content ($parser, $content)
    {
        echo "$this->tag: $content" ;
    }
}

Then in your code:

$xml = "<a>bah</a>";
XML::parse($xml, new ResultHandler());

Note that HTML/XML entities are considered to be tags by PHP's XML parser, so your start tag handler will be called three times for this tag, once for "really", once for "&" and once for " bad parser":

<data>really &amp;  bad parser</data>

I guess this is a bug... You can