tag ‍“php”

how to use phing to build php projects

by Hamid Reza Fahimi Madjd @ Jun 25, 2011

Some days ago I found a solution to build php project that called Phing.
Phing is a build framework based on Apapche Ant. If you are familiar with Ant and its role in Java *E projects, you can learn Phing very fast.
Like Ant, there is a (or more) build file named build.xml (default name) to define operations that you like occur on your project.

Now i'm going to describe it by a practical example:

Consider a php project with following structure:

Project
|_src
|__package1
|___class1.php
|___class2.php
|__package2
|__package3
|_static
|_templates
.htaccess
build.xml
config.php
index.php

Scenario:
I want "build.xml" do following operations:

  1. export project from subversion repository and copy it to a temp directory
  2. make an archive file and name it based on latest version number
  3. copy archive file to a remote server over ssh (scp)

I made build.xml file put following code in it:

<?xml version="1.0" encoding="UTF-8"?>
<!-- define project name and default target -->

<project name="my-project" default="dist">

<!-- define some properties (variables) -->
  <property name="path.dive.root" value="/home/hamid/temp" />
  <property name="path.dive" value="${path.dive}/${phing.project.name}" />

<!-- empty related temp directory (delete old one and create new one) -->
  <target name="prepare">
    <echo msg="delete and create ${path.dive} directory" />
    <delete dir="${path.dive}" includeemptydirs="true" verbose="true" failonerror="true" />
    <mkdir dir="${path.dive}" />
  </target>

  <target name="build" depends="prepare">

<!-- export project from reposiroey and copy to temp directory -->
    <svnexport
    svnpath="/usr/bin/svn"
    username="username" password="password"
    force="true" nocache="true"
    repositoryurl="svn://localhost/${phing.project.name}/"
    todir="${path.dive}"/>

<!-- get latest version number and save in svn.lastrevision property -->
    <svnlastrevision
    svnpath="/usr/bin/svn"
    workingcopy="${path.source}"
    repositoryurl="svn://localhost/${phing.project.name}"
    propertyname="svn.lastrevision"/>

<!-- generate archive file name -->
   <property name="archive.filename" value="${phing.project.name}-v${svn.lastrevision}.tar.gz" />
  </target>

  <target name="dist" depends="build">

<!-- archive directory and save it -->
    <tar destfile="${path.dive.root}/${archive.filename}" basedir="${path.dive}" compression="gzip"/>

<!-- copy archive file and copy to sources foler on remote server -->
    <scp username="username" password="password"
    host="host"
    todir="sources/"
    file="${path.dive.root}/${archive.filename}" />
  </target>
</project>

after that go to path that build file is there and type:

$ phing

cause build file name is build.xml, it's not necessary to specify it.
Also if you use PhpStorm, you can add build.xml to Phing Build tool window and deal with that inside the IDE.
Now, I did build process just in 10 Seconds instead of 5 Minutes.

I hope this example encourage you to use Phing.
You can get more detail information from its website.

phing, php comments no comment

slice/paging large contents using php

by Hamid Reza Fahimi Madjd @ Nov 28, 2010

Some days ago i was engaged in wap version of a web based application that had to prepare large content (like articles) for mobile devices.

considering limitation of mobile devices, i decided to slice content to specified bytes (1500 Bytes) and display sliced content instead whole content.

so i wrote a snip code that :

  1. fetch specified bytes
  2. continue to fetching (in both side, left and right) untill get first new line character
define('BYTES_PER_PAGE', 1500);
define('PAGE_NO', ((int)@$_GET['page']) == 0? 1: (int)@$_GET['page']);
$len = mb_strlen($description, 'utf-8');

if($len > BYTES_PER_PAGE) {
  $len = ($len%BYTES_PER_PAGE == 0? (int)$len/BYTES_PER_PAGE: (int)($len/BYTES_PER_PAGE)+1 ) ;
  $start = (PAGE_NO - 1) * BYTES_PER_PAGE;
  $end = PAGE_NO * BYTES_PER_PAGE;

  // go back till get first new line char
  while($start > 0 && ord(mb_substr($description, --$start, 1, 'utf-8')) != 10);

  // go forward till get first new line char
  while($end < mb_strlen($description, 'utf-8') && ord(mb_substr($description, $end++, 1, 'utf-8')) != 10);
  $description = mb_substr($description, $start, $end-$start, 'utf-8');
}

as you see, because of utf8 string, i used  mb_* functions, you can replace it with normal string functions.

php comments no comment

how to log methods call in php ?

by Hamid Reza Fahimi Madjd @ Oct 6, 2010

as you know there are a lot of logging api that you can use theme to follow users activity, errors and etc. but i needed a logging api that log methods call and their passed variable through them.

so i wrote a snip code using debug_backtrace function and ReflectionMethod class to do that, i made 2 tables named activity_log to save called method information and activity_log_param to save parameteres name and its (serialized) value:

class Log {
  protected function log($result, $message = null) {
    $activitySql = 'insert into activity_log(caller, class, method, method_type, result, message, ip, agent) '.
        'values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';

    $pure = next(debug_backtrace(false));
    // create a mysql query object and run the query using bind parameters and return generated autoincrement id
    $newOid = QueryBuilder::create($activitySql)->write(array(
        $pure['file'],
        $pure['class'],
        $pure['function'],
        $pure['type'],
        $result,
        $message,
        getIp(),
        getUserAgent()
      ),true);

    $paramsSql = 'insert into activity_log_param(fk_activity_log_oid, pname, pvalue, serialized) values ';

    $reflectionMethod = new ReflectionMethod($pure['class'] . '::' . $pure['function']);
    $pNames = $reflectionMethod->getParameters();
    $pValues = $pure['args'];
    $tmp = '';

    foreach($pNames as $idx=>$obj) {
      $pValue = null; $serialized = 'no';
      if(!isset($pValues[$idx])) {
        $pValue = null;
      }
      else {
        if(is_object($pValues[$idx])) {
          $pValue = serialize($pValues[$idx]);
          $serialized = 'yes';
        }
        elseif(is_array($pValues[$idx])) {
          $pValue = serialize($pValues[$idx]);
          $serialized = 'yes';
        }
        else {
          $pValue = $pValues[$idx];
        }
      }
      $tmp .= '(' . $newOid . ', '' . $obj->name . '', '' . $pValue . '', '' . $serialized . ''), ';
    }
    if(!empty($tmp)) {
      $paramsSql .= substr($tmp, 0, -2) . ';';
      return QueryBuilder::create($paramsSql)->write();
    }

  }
}

because debug_backtrace() function doesn't return parametere name, i used ReflectionMethod class to get parameters name.

how to use it? inherit your class from Log class and call log() method to log called method information:

CLass MyClass extends Log {
  public function foo($oid, array $sampleArray, Object $sampleObject) {
    parent::log(true, 'done');
  }
}

 

php comments no comment

last tweet