A piggy bank of commands, fixes, succinct reviews, some mini articles and technical opinions from a (mostly) Perl developer.

Jump to

Quick reference

Showing posts with label php. Show all posts
Showing posts with label php. Show all posts

PHP, pecl, phpize PDO, mysqli for Perl devs

"pecl" is the same as "cpan"
"phpize" is the equivalent of "perl Makefile.pl"
"PDO" is PHP's DBI equivalent (i.e. general purpose RDBMS connector)
"mysqli" is the more modern version of the mysql-specific connector

Importing with Wordpress

If you get a 500 Internal Server Error while importing a large file in Wordpress:

  • Just keep refreshing the page and re-submitting the data.
  • Items will continue to be added (and downloaded) a few at a time, and no item will be added twice.
Eventually all the data will be imported correctly.

Debugging websites

CSS:
element {
    outline: red solid thick;
    background: green;
};

PHP:
<?php $debug = $_GET['debug'] ?>

Parse XML in PHP

http://php.net/manual/en/function.file-get-contents.php - fetch URL
http://php.net/manual/en/simplexmlelement.xpath.php - parse XML
http://www.php.net/manual/en/simplexml.examples-basic.php - register namespaces, etc.

Example for Google calendar. Most important parts are the namespaces and (string) casting.

    $contents = file_get_contents($calendar_url); // should end with 'full', not 'basic'
    $xml = new SimpleXMLElement($contents);

    $namespaces = $xml->getDocNamespaces();
    $xml->registerXPathNamespace('__empty_ns', $namespaces['']);
    $xml->registerXPathNamespace('gd', 'http://schemas.google.com/g/2005'); # xmlns:gd='http://schemas.google.com/g/2005'

    $entries = $xml->xpath("//__empty_ns:entry");
    while(list( , $node) = each($entries)) {
        $time_nodes = $node->xpath("gd:when/@startTime");
        while ($time_node = each($time_nodes)) {
            # <gd:when endTime="2011-08-19T17:00:00.000+01:00" startTime="2011-08-19T14:00:00.000+01:00"></gd:when>

            $time_text = (string)$time_node[1]->startTime;

            die "time = $time_text\n";

How to add a custom PHP page to phpBB3

There is a tutorial explaining how to add a static HTML page, with phpBB header and footer.
This is how to add a dynamic PHP page in a similar way:
  1. Go to ACP | General | Security settings, and set "Allow php in templates" to "Yes".
  2. Follow the tutorial at: http://wiki.phpbb.com/Practical.Add_custom_page
  3. In the template (e.g. about_us.html), replace where it says "Content in here" with <!-- INCLUDEPHP relative/path/to/your/php/page.php -->

Log and email your Apache errors

In the .htaccess at the root of the site:
ErrorDocument 404 http://www.example.com/error_page.php?err=404
ErrorDocument 503 http://www.example.com/error_page.php?err=503
etc.

In error_page.php:


$myemail = "someone@example.com";
$subject = "example.com: $errorNum error";
$message = "$errorNum Error Report:\n";
$message .= "\nHTTP_REFERRER: ".$_SERVER['HTTP_REFERER'];
$message .= "\nREQUEST_URI: ".$_SERVER['REQUEST_URI'];
$message .= "\nHTTP_USER_AGENT: ".$_SERVER['HTTP_USER_AGENT'];
$message .= "\nQUERY_STRING: ".$_SERVER['QUERY_STRING'];
$message .= "\nREMOTE_ADDRESS: ".$_SERVER['REMOTE_ADDR'];


ob_start();
print "\n\nSERVER = "; print_r( $_SERVER );
print "\nGET = "; print_r( $_GET );
print "\nPOST = "; print_r( $_POST );
print "\nFILES = "; print_r( $_FILES );
print "\nREQUEST = "; print_r( $_REQUEST );
print "\nSESSION = "; print_r( $_SESSION );
print "\nENV = "; print_r( $_ENV );
print "\nCOOKIE = "; print_r( $_COOKIE );
print "\nprevious php_errormsg = "; print_r( $php_errormsg );
print "\nargv = "; print_r( $argv );
$output = ob_get_clean();
$message .= "\n\n$output\n";


# email the error
mail($myemail,$subject,$message,"From: support@example.com");


# log the error
$myFile = "logs/error.".date('Y_m_d-H.i.s').".log";
$fh = fopen($myFile, 'w');
$stringData = $message;
fwrite($fh, $stringData);
fclose($fh);
?>

How to customise the "content edit form" in Drupal

/**
* Catch the theme_node_form function, and redirect through the template api
* Allows us to customise the fields displayed on the "create content" form
*/
function phptemplate_node_form($form) {
$admin_role_id = 3;

if ((! $user->roles[ $admin_role_id ]) && ($user->uid != 1)) {
// user is not an admin, hide all the advanced fields

// Default Drupal fields
unset($form['attachments']);
unset($form['options']);
unset($form['author']);
unset($form['comment_settings']);
unset($form['revision_information']);
unset($form['menu']);
unset($form['body_field']['format']);
unset($form['path']);
//$form['format']['#title'] = 'Advanced setting: Input format'; // e.g. rename fields

// Ubercart fields
//unset($form['base']); // note: can't submit without this because display price and SKU are required
//unset($form['taxonomy']);
//unset($form['field_image_cache']);
//unset($form['google_checkout']);

// call the original function
return theme_node_form($form);
}

Set up sendmail on linux desktop

Setting up email sending (not receiving) for XAMPP in Ubuntu.

Install Postfix:
  • sudo apt-get install postfix
  • Choose satellite system
  • Choose example.com for the system mail name (it will mean the 'hidden' Return-Path address goes to nothing, not the visible From/Reply-to address)
  • Type your ISP's SMTP address
  • Type a user for incoming email
  • Just accept the defaults for other questions
If you need to reconfigure, do sudo dpkg-reconfigure postfix

To check the version, do postconf -d | grep mail_version

PHP/XAMPP settings:
  • In php.ini, add: sendmail_path = /usr/sbin/sendmail -t
Test like this:



$email = 'you@yourdomain.com';
$headers = "From: $email\r\n";
$headers .= "Reply-To: $email\r\n";
$subject = "test subject";
$message = "test body";
print mail($email,$subject,$message,$headers) . "\n";

?>

Simple PHP email form

The 'hidden' Return-Path header (not visible Reply-To) will be your name at your domain.

Email form:

<form method="post" action="s.php">
From: <input name="from" type="text" /><br />
To: <input name="to" type="text" /><br />
Subject: <input name="subject" type="text" /><br />
Body:<br />
<textarea name="body" rows="15" cols="40">
</textarea><br />
<input type="submit" value="send"/>
</form>


s.php:

<?php
$to = $_REQUEST['to'] ;
$from = $_REQUEST['from'] ;
$subject = $_REQUEST['subject'] ;
$body = $_REQUEST['body'] ;

$return = mail( $to, $subject, $body, "From: $from\r\nReply-To: $from" );

if ($return == 1) {
print "sent.";
}
else {
print "error.";
}
?>

Display output of XSL transformation using PHP

Use XAMPP or similar to serve (reportedly works on PHP 5):

<?
$query = $_GET['q'];
$filePath = 'http://source-server:8889/page/'.$query;

$xslDoc = new DOMDocument();
$xslDoc->load("http://localhost/xslt/page_render.xsl");
$xmlDoc = new DOMDocument();
$xmlDoc->load( $filePath );

$proc = new XSLTProcessor();

$proc->importStylesheet($xslDoc);
echo $proc->transformToXML($xmlDoc);
?>

No XSLT2 in PHP

There is only one known xslt2 processor called SAXON (http://saxon.sourceforge.net/), built by Michael Kay, which was released for the Java and .NET platforms.

Other XSLT processors, including Sablotron, Xalan and MSXML, have not yet adopted xslt2.

Kay writes: "implementation [for xslt2 in php] does not exist because no-one has written one". He continues, "The usual workaround I recommend is to implement XSLT 2.0 transformation as a (Java-based or .NET-based) REST web service, and for the php application to submit transformation requests to that web service by means of HTTP requests. An alternative is to use a php-Java bridge"

Michael Kay manages an email-based discussion group called MulberryTech, a good resource for learning XSLT techniques (both 1 and 2). (http://www.mulberrytech.com/xsl/xsl-list/)


How to find which function does what in Drupal 6

A forum post describes how to find the right function by hacking a core file.

In Drupal 6, inside the theme() function of /includes/theme.inc, change line 617 from this:

$output = call_user_func_array($info['function'], $args);

To this:

$output = '<!-- begin ' . $info['function'] . ' -->' . call_user_func_array($info['function'], $args) . '<!-- end ' . $info['function'] . ' -->' ;

The advice about not doing this on a production site stands.


Taxonomy menu for Drupal

<?php
$vid = 1; /* <---- put correct vocabulary ID here */
$terms = taxonomy_get_tree($vid);
print "<div class=\"item-list\">";
print "<ul>";
foreach ( $terms as $term ) {
$tcount = taxonomy_term_count_nodes($term->tid);
print "<li>".
l($term->name." (".$tcount.")",'taxonomy/term/'.$term->tid, array('title' => $tcount." posts in ".$term->name)).
"</li>";
} /* end foreach */
print "</ul>";
print "</div>";
?>

How to use PHP snippets in Drupal

Enable the core 'PHP filter' module, then select the PHP filter from the 'input formats' list when creating a page.

PHP 5 XML

SimpleXML
http://www.php.net/manual/en/ref.simplexml.php

$xml = simplexml_load_file($file);

$body = $xml->xpath("//body");

print $body->asXML();


PHP 4 XSL

XSLT extension (for PHP 5, use XSL)
http://www.php.net/manual/en/intro.xslt.php

NOTE:
This extension uses Sablotron and expat, which can both be found at http://www.gingerall.org/sablotron.html. Binaries are provided as well as source.

You must run configure with the --enable-xslt --with-xslt-sablot options.


<?php

$xml 
= <<<EOT
<?xml version="1.0"?>
<hello-world>
    <greeter>An XSLT Programmer</greeter>
    <greeting>Hello, World!</greeting>
</hello-world>
EOT;

$xsl = <<<EOT
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/hello-world">
    <HTML>
      <HEAD>
        <TITLE></TITLE>
      </HEAD>
      <BODY>
        <H1>
          <xsl:value-of select="greeting"/>
        </H1>
        <xsl:apply-templates select="greeter"/>
      </BODY>
    </HTML>
  </xsl:template>
  <xsl:template match="greeter">
    <DIV>from <I><xsl:value-of select="."/></I></DIV>
  </xsl:template>
</xsl:stylesheet>
EOT;

$arguments = array(
     
'/_xml' => $xml,
     
'/_xsl' => $xsl
);

// Allocate a new XSLT processor
$xh = xslt_create();

// Process the document
$result = xslt_process($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments);
if (
$result) {
    echo 
"SUCCESS, sample.xml was transformed by sample.xsl into the \$result";
    echo 
" variable, the \$result variable has the following contents\n<br />\n";
    
//echo "<pre>\n";
    
echo $result;
    
//echo "</pre>\n";
} else {
    echo 
"Sorry, sample.xml could not be transformed by sample.xsl into";
    echo 
"  the \$result variable the reason is that " . xslt_error($xh);
    echo 
" and the error code is " . xslt_errno($xh);
}
xslt_free($xh);

?>

PHP for Mac OSX

PHP arrays

This won't work:
php -r "$a = array( 'c' => array( 'b' => 1 ) );"

But this will:
php -r '$a = Array( "c" => Array( "b" => 1 ) );'

On Mac OSX

PHP command line

php -f file.php

file.php contains:
<?php
print "hello world";
?>

or a one-liner:

php -r "some code;"

Don't forget the trailing semicolon.