Showing posts with label PHP. Show all posts
Showing posts with label PHP. Show all posts

Wednesday, October 17, 2018

Prevent joomla tinyMCE editor from not displaying image when copy paste content from other website.


I have a knowledge base site built with joomla. Recently, I found images does not shown when we copy&paste web page content from other sites.

This happens because original web pages put crossorigin="anonymous" in their tags. So, as long as joomla tinyMCE filters out this img attributes, those images will be shown again.

To solve this, a quick walk around is finding an tinyMCE plugin and register it in joomla. this plugin will filter out crossorigin attribute when content is pasted into tinyMCE textarea. As a quick dirty solution, I use tinyMCE paste plugin found in plugins directory. And modified two places as below.





java script

Open file:
/var/www/html/media/editors/tinymce/plugins/paste/plugin.min.js


Add below content marked as red,

function insertClipboardContent(clipboardContent, isKeyBoardPaste, plainTextMode, internal) {
        var content, isPlainTextHtml;
        if (hasContentType(clipboardContent, 'text/html')) {
          content = clipboardContent['text/html'];
        } else {
          content = pasteBin.getHtml();
          internal = internal ? internal : InternalHtml.isMarked(content);
          if (pasteBin.isDefaultContent(content)) {
            plainTextMode = true;
          }
        }
        content = Utils.trimHtml(content);
        //should use Dom parser for robust coding. 
        content = content.replace(/crossorigin=\"anonymous\"/gi,'');

    



chown apache:apache plugin.min.js


sudo chmod 644 plugin.min.js


PHP

Open below file,
/var/www/html/plugins/editors/tinymce/tinymce.php

Add below content marked as red,

// Drag and drop Images
        $allowImgPaste = false;
        $dragdrop      = $levelParams->get('drag_drop', 1);

        $externalPlugins['jpaste'] = JUri::root() . 'media/editors/tinymce/plugins/paste/plugin.min.js'; 



 $externalPlugins = array(
                array('jdragdrop' => JUri::root() . 'media/editors/tinymce/js/plugins/dragdrop/plugin.min.js'),
                array('jpaste' => JUri::root() . 'media/editors/tinymce/plugins/paste/plugin.min.js'),
            );



Above is just a quick dirty walk around. Creating a dedicate tinyMCE plugin for filtering should be a better neat solution.




Saturday, January 28, 2012

Multi-threaded application (Java) or Multi-process application (PHP) for Hyper Threading enabled CPU

There are many factors affect an application's performance. Today, hyper threading enabled multi-core CPU becomes so popular. Naturally, we are expecting to have better performance on these modern CPU. I am not eligible to discuss about question about how to optimize application for a hyper threading multi-core CPU yet. But, I do ask myself this question: which one, a muli-threaded application or a multi-process application, can get more benefit from a hyperthreaded CPU? In other words, for a computing intensive task, should I design it as a multi-threaded application or a multi-process application? To be more specific, does Java, which support multi-threaded programming, has advantage over the PHP on a hyper threading enabled CPU or PHP actually has advantage over the Java? I had a discussion about "Can two processes simultaneously run on one CPU core?". Here, let me highlight some points I studied for answering my questions.

Software Thread
We know software thread is a lightweight process. Once process can contains multiple thread. Software thread is managed by OS. OS decide which CPU/CORE/ the thread will run in. Application programmer can also control where the thread can run by using affinity library. Typically, we need multiple thread application when it has I/O latency and we do not want to hang other computing task. For example, We do not want a desktop having GUI stop response user's input when it is running other computing or I/O task. Also, we normally need thread pool to have initialized ready to serve threads for a service application.

Hardware Thread
A hardware thread is pipeline for a software thread to reach CPU's physical core. In a HT CPU, a physical core can have two hardware threads (logical cores) as it has extra registers and execution units and it therefore stores the state of two threads.

What is shared among software threads and what is not
Multiple software threads (kernel thread) can live inside a process. In other words, they can not share anything out of process' resource. A kernel thread is the lightest unit for OS' kernel scheduling. Kernel threads do not share their stack, a copy of the registers including the program counter, and thread-local storage.

It is called "green thread" if the thread is implemented in "user space". green thread is not seen by kernel. It is normally useful for debugging a multi-threaded application.

What is shared among processes
I do not know what is shared among processes from point view of CPU. A process is the biggest unit of kernel scheduling. It has its own resources including memory, file handles, sockets, device handles etc. Processes has its own address spaces, shared by its containing threads. Of course, programmer can explicitly call methods to share resources with other process such as shared memory segments.

History about CPU evolution To better understand how to get most benefit from modern multi-core, HT CPU, I feel I need to study the history of CPU architecture evolution. But, I do not have time to do this yet. Let me deeply study it later.

Now, let's come back to my original questions. A normal application contains lots latency operations. For examples, a application normally contains network I/O, file I/O, or GUI interactivity. In this case, which is typical reason for us to use multi-threaded techniques, hyper threading can improve performance at little cost. However, hyper-threading is often turned off in high performance systems as hyper threading can impact performance when the two threads on the same core start competing for resources, such as the FPU, Level 1 cache, or CPU pipeline. We can see some motherboard actually disable hyper-threading by default.

Also, swap thread's context is expensive too. To switch threads system has to empty the registers into the cache, write that back to the main memory, then load up the cache with the new values and load up the registers. So, we need to be careful not to make overhead threads in our application.

The good way is probably keep same number of running threads as number of logical core. However, in the real world, many threads in an application are blocked thread. For a application having much more software thread than hardware thread, I will expect most of them are blocked thread. For example, a web server may have larger number of thread serving HTTP request. It has no problem as they are all blocked thread as it may be blocked at network I/O.

BTW, the coming up Reverse-Hyperthreading, which spread a thread's computing task among different logical core, may introduce new opportunity into multi-threaded programming world. But, who knows if it will actually bring in more challenges.

So, back to my original question, I still think java has chance to get more benefits from a hyper-threading enabled CPU than PHP does as core PHP does not directly support multi-threading programming. However, a bad designed multi-threading may even damage the performance. Here is a good document for me to better understand hyper threading technology: Performance Insights to Intel® Hyper-Threading Technology
http://stackoverflow.com/questions/1888160/distinguish-java-threads-and-os-threads http://stackoverflow.com/questions/8916723/can-two-processes-simultaneously-run-on-one-cpu-core http://stackoverflow.com/questions/4771205/dual-core-hyperthreading-should-i-use-4-threads-or-3-or-2?rq=1 http://stackoverflow.com/questions/360307/multicore-hyperthreading-how-are-threads-distributed?rq=1 http://stackoverflow.com/questions/508301/on-which-operationg-system-is-threaded-programming-sufficient-to-utilize-multipl http://software.intel.com/en-us/articles/performance-insights-to-intel-hyper-threading-technology/ http://stackoverflow.com/questions/2238272/java-thread-affinity http://java.dzone.com/articles/java-thread-affinity-support http://www.codeguru.com/cpp/sample_chapter/article.php/c13533/Why-Too-Many-Threads-Hurts-Performance-and-What-to-do-About-It.htm http://msdn.microsoft.com/en-us/magazine/cc872851.aspx

Thursday, December 8, 2011

java vs php benchmark (cited from The Computer Language Benchmarks Game )

I saw a benchmark between Java 7 and PHP. I do not know how precisely the benchmark is. But, I will believe this result. Besides running speed and memory usage, there are many other factors affect us to choose Java or PHP as programming language. But, it is always interesting and valuable to be able to have a rough idea about this kind comparison.

Below is cited from http://shootout.alioth.debian.org/ . Interested can go there for detail.

This chart shows 3 comparisons - Time-used, Memory-used and Code-used ~ speed and size.
Each chart bar shows, for one unidentified benchmark, how much the fastest Java 7 -server program used compared to the fastest PHP program.

Friday, November 18, 2011

IBM DB2 extension has no limitation on number of opened persistent PHP DB2 connection.

To further study how to optimize PHP DB2 connection, I looked into PHP DB2 extension again recently. I want to find out the best way to use persist connection with considering about ODP reusing.

After reading the source code of PHP DB2 extension, I noticed that there is no limitation of maximum number of pconnection from PHP DB2 extension. In the C code, we can see only UserID, password, and Database name are used to compose hash code. You locate the place by search following code in the source code.

sprintf(hKey, "__db2_%s.%s.%s", uid, database, password);

This is interesting as it implies that I should avoid allowing huge number of different user profile to be used inside one Zend Server.

I am thinking that we will have difficult to reuse ODP when only userId, password, and database name are used to generate hash code for pconnect because ODP will be reused based on not only user name and password. For example, I think the ODP will be rebuilt if different requests use same User Name and password but different library list to get pconnection. PHP Db2 extension allows us to pass in library list. So, if developers, for some reason, happen to pass in different library list to run query on same library, the ODP will be rebuilt for sure.

Some other things I do not have answers are,

1) What happens to pconnection if its associated QSQSRVR job is terminated for some reason?

2) I saw something about ODBC version occur in C code. Does PHP DB2 extension works with ODBC in any way?

Sunday, August 28, 2011

install xdebug with Zend Server CE and Netbeans 7.0.x

Go to Fedora "Application -> System Tools -> Add/Remove Software" and make sure PHP PEAR and PHP PECL and XDebug are installed already. Then, run the following commands to add xdebug into Zend Server.

#  edit debugger.ini file to disable zend debugger.
#  ; register the extension to be loaded by Zend Extension Manager
# ;zend_extension_manager.dir.debugger=/usr/local/zend/lib/debugger
[root@jiaFedora14 yyjia]# sudo gedit /usr/local/zend/etc/conf.d/debugger.ini

#find where is xdebug.so
[root@jiaFedora14 /]# find /usr/ -name 'xdebug.so'
/usr/lib64/php/modules/xdebug.so

#  Make zend server to load xdegug.so before extension manager is loaded.
#  zend_extension=/usr/lib64/php/modules/xdebug.so
#  zend_extension=/usr/local/zend/lib/ZendExtensionManager.so
[root@jiaFedora14 yyjia]# sudo gedit /usr/local/zend/etc/conf.d/extension_manager.ini

# edit php.ini or other configuration files to have xdebug settings
# [xdebug]
# xdebug.remote_enable=on
# xdebug.remote_handler=dbgp
# xdebug.remote_mode=req
# ;xdebug.remote_connect_back=1
# xdebug.remote_host=192.168.1.190
# xdebug.remote_port=9001
# xdebug.idekey="netbeans-xdebug"
[root@jiaFedora14 yyjia]# sudo gedit /usr/local/zend/etc/php.ini

# Fedora has SELinux enabled by default. I open the port 9001.
[root@jiaFedora14 yyjia]# semanage port -a -t http_port_t -p tcp 9001

# restart Zend Server
[root@jiaFedora14 yyjia]# service zend-server restart

# check xdebug configuration.
[root@jiaFedora14 yyjia]# php -i | grep xdebug

After running all above command and see every thing is correct as expected, we do a simple configuration in Netbeans as shown in figure below,




Some notes:
1) The above steps only install xdebug for one developer. For a team developing environment, we need to install DBGp proxy.

2) I tried "xdebug.remote_connect_back=1" and hope I do not need to specify a fix hostname/ipaddress in php.ini. But, I failure on it. I have not dig deep into it.

Friday, July 1, 2011

ExtJS 4 REST proxy and Zend framework Zend_Rest_Route are incompatible.

I noticed a very strange thing when I worked on Ext JS 4 v4.0.2 and Zend Framework. I find that every time when Ext JS grid sends new created Record to the server through its REST proxy, the POST method was teated as PUT method in Zend_Rest_Route. This cause troublesome because my code have to know if the incoming record a new one for insert or exsiting one for update. Otherwise, I have to use some UPSERT SQL statement to UPDATE or INSERT record into Database table. Unfortunately, I use DB2 for i5/OS V5R4, which does not have built-in UPSERT command and it even does nor support MERGE statement.

I do not want to walkaround this by doing SELECT first and judging if the code need to run INSERT or UPDATE statement. So, I traced the Ext JS 4 code and Zend Framework 1.11 code. I found that these two are not compatiable. I am not sure if we can say it is BUG as this wont happen if either side change their code. Or, both side can change the code to avoid the confilicaton if we say bugs are from both sides.

The key for this issue is that Ext JS 4 append record's id at the end of base URL, which points to RESTful service. Below is a psuedo POST URL create by Ext JS 4 REST proxy. I highlight the unexpected friend in red color.

http://hostname/yourRestServiceURI/yourRecordId/?dc=randomNum


We understand that adding record id as part of URI can allow server side script easily find it. But, why this design is implemented in a general SDK like Ext JS? Especially, I do not see good reason for a POST request to have it as record in POST are suppoe not to have been existing on server side. Therefore, the ID of the new record might not have been generated if it will be generated on the server side only.

In Ext JS 4 source code \src\data\proxyRest.js, we can see what happens,
/**
     * Specialized version of buildUrl that incorporates the {@link #appendId} and {@link #format} options into the
     * generated url. Override this to provide further customizations, but remember to call the superclass buildUrl
     * so that additional parameters like the cache buster string are appended
     */
    buildUrl: function(request) {
        var me        = this,
            operation = request.operation,
            records   = operation.records || [],
            record    = records[0],
            format    = me.format,
            url       = me.getUrl(request),
            id        = record ? record.getId() : operation.id;
        
        if (me.appendId && id) {
            if (!url.match(/\/$/)) {
                url += '/';
            }
            
            url += id; //Why add ID here even for POST? Yiyu Jia
        }
        
        if (format) {
            if (!url.match(/\.$/)) {
                url += '.';
            }
            
            url += format;
        }
        
        request.url = url;
        
        return me.callParent(arguments);
    }
}

Now, people will ask why adding id in URL cause the problem in Zend Framework? Well, let's trace Zend Framework code now.

On Zend Framework API document about Zend_Rest_Route, we can see Zend clearly described their design how RESTful URI should looks like,
Zend_Rest_Route Behavior
MethodURIModule_Controller::action
GET/product/ratings/Product_RatingsController::indexAction()
GET/product/ratings/:idProduct_RatingsController::getAction()
POST/product/ratingsProduct_RatingsController::postAction()
PUT/product/ratings/:idProduct_RatingsController::putAction()
DELETE/product/ratings/:idProduct_RatingsController::deleteAction()
POST/product/ratings/:id?_method=PUTProduct_RatingsController::putAction()
POST/product/ratings/:id?_method=DELETEProduct_RatingsController::deleteAction()

As we can see, Zend Framework does not expect any thing attached to method URI when PHP programmer intend to use POST method. In Zend_Rest_Route source code, we can see a case switch statement as below. You will see when the POST method will be "magically" routed to PUT method if pathElementCount is larger than zero.

switch( $values[$this->_actionKey] ){
                    case 'post':
                        if ($pathElementCount > 0) {
                            $values[$this->_actionKey] = 'put';
                        } else {
                            $values[$this->_actionKey] = 'post';
                        }
                        break;
                    case 'put':
                        $values[$this->_actionKey] = 'put';
                        break;
                }


But, where is the $pathElementCount set? In the same source code file, we can see below statement,

//Store path count for method mapping
$pathElementCount = count($path);

So, where is value of $path populated? Still, in the same source code, there is a function call match. Part of it is cited as below.

/**
     * Matches a user submitted request. Assigns and returns an array of variables
     * on a successful match.
     *
     * If a request object is registered, it uses its setModuleName(),
     * setControllerName(), and setActionName() accessors to set those values.
     * Always returns the values as an array.
     *
     * @param Zend_Controller_Request_Http $request Request used to match against this routing ruleset
     * @return array An array of assigned values or a false on a mismatch
     */
    public function match($request, $partial = false)
    {
        if (!$request instanceof Zend_Controller_Request_Http) {
            $request = $this->_front->getRequest();
        }
        $this->_request = $request;
        $this->_setRequestKeys();

        $path   = $request->getPathInfo();
        $params = $request->getParams();
        $values = array();
        $path   = trim($path, self::URI_DELIMITER);

Ok, now, it is not the end of code tracing yet. Where is the getPathInfo() function? It is in Zend_Controller_Request_Http. The following code citation will show us that getPathInfo() eeturns everything between the BaseUrl and QueryString and deos something special.

/**
     * Returns everything between the BaseUrl and QueryString.
     * This value is calculated instead of reading PATH_INFO
     * directly from $_SERVER due to cross-platform differences.
     *
     * @return string
     */
    public function getPathInfo()
    {
        if (empty($this->_pathInfo)) {
            $this->setPathInfo();
        }

        return $this->_pathInfo;
    }

/**
     * Set the PATH_INFO string
     *
     * @param string|null $pathInfo
     * @return Zend_Controller_Request_Http
     */
    public function setPathInfo($pathInfo = null)
    {
        if ($pathInfo === null) {
            $baseUrl = $this->getBaseUrl(); // this actually calls setBaseUrl() & setRequestUri()
            $baseUrlRaw = $this->getBaseUrl(false);
            $baseUrlEncoded = urlencode($baseUrlRaw);
        
            if (null === ($requestUri = $this->getRequestUri())) {
                return $this;
            }
        
            // Remove the query string from REQUEST_URI
            if ($pos = strpos($requestUri, '?')) {
                $requestUri = substr($requestUri, 0, $pos);
            }
            
            if (!empty($baseUrl) || !empty($baseUrlRaw)) {
                if (strpos($requestUri, $baseUrl) === 0) {
                    $pathInfo = substr($requestUri, strlen($baseUrl));
                } elseif (strpos($requestUri, $baseUrlRaw) === 0) {
                    $pathInfo = substr($requestUri, strlen($baseUrlRaw));
                } elseif (strpos($requestUri, $baseUrlEncoded) === 0) {
                    $pathInfo = substr($requestUri, strlen($baseUrlEncoded));
                } else {
                    $pathInfo = $requestUri;
                }
            } else {
                $pathInfo = $requestUri;
            }
        
        }

        $this->_pathInfo = (string) $pathInfo;
        return $this;
    }

So, what is the conclusion? The conclusion is that both Ext JS and Zend framework has their own design of RESTful URI pattern. Unfortunately, they are not compatible with each other. They are too nice to do more than developer expected. As libraries vendor, they maybe should do less sometimes in order to make their library as general as possible. Ext JS, as a pure client side JavaScript library, should not guide server side script designer how to implement RESTful Web service. Zend Framework, as a pure server side script library, should not make design for client side application either. In fact, RESTful Web service is a set of guide lines for developer to make scalable application over HTTP methods. But, it does not define how the URI pattern must be.

Tuesday, March 22, 2011

Zend Server for IBM iSeries platform does not support multiple persistent connection to DB2

_
_
Edit: This post's content may only apply to i5/OS V5R4 without latest PTF. Please refer to comments for detailed info.

Persistent connection in PHP has its advantage and disadvantage. According to my observation about creating DB2 connection on i5/OS, time used to set up connection via normal connection and persistent connection can be 50 ~ 100 times different. However, persistent connection has its disadvantage as well. Some php programmer even call it evil. Also, it might not be worthy to take risk from persistent connection if the access traffic is not so high.

In a brief way to describe, the causer for persistent connection has disadvantage is that PHP itself is a stateless script language and database connection is usually stateful. That is, php script's life time only exists from the request coming and request end. Meanwhile, database connection will hold some state like table lock, user defined variables etc. So, the problem will occur when a php script use a persistent connection as a fresh new connection and it is not. PHP persistent does not support a kind of "private" connection, which will be used by one user session only. This kind private connection implementation can be found in easyComm i5 toolkit.

Back to what I observed recently. I find that Zend Server (ver 5.0.4) for IBM i5/OS V5R4 does not supports having multiple persistent connection in one request to php scripts. Below is a simple testing code. When you run it, you can see that the output Current Schema is not ALWAYS as what you specified in db2 connection string. I guess the hash function used Zend Server for resource manager may has some problem. Or, DB2 extension has a bug if it does not intend to support only one persistent connection in one PHP script request.

Change the db2_pconnect to db2_connect to see different output. You need to run this script many times to see that you can not ALWAYS get the right schema as your current schema. Most likely, you need to take 5 minutes to 10 minutes break during the testing and see the wrong result to come out.


<?php 

$sysStr = 'select CURRENT SCHEMA from SYSIBM.SYSDUMMY1 ';

$params = array(
 'username' => 'accountNameOne', 
 'password' => 'accountPwdOne',
 'dbname' => '*LOCAL', 
 'driver_options' => array('i5_lib' => 'libraryOne')
);
$connOne = db2_pconnect($params['dbname'], $params['username'], 
$params['password'], $params['driver_options']);
$sysStmt = db2_prepare($connOne, $sysStr);
db2_execute($sysStmt);
$returnObj = db2_fetch_object($sysStmt);
var_dump($returnObj);

$params2 = array(
 'username' => 'accountNameTwo', 
 'password' => 'accountPwdTwo', 
 'dbname' => '*LOCAL', 
 'driver_options' => array('i5_lib' => 'libraryTwo')
);
$connTwo = db2_pconnect($params2['dbname'], $params2['username'], 
$params2['password'], $params2['driver_options']);
$sysStmt2 = db2_prepare($connTwo, $sysStr);
db2_execute($sysStmt2);
$returnObj2 = db2_fetch_object($sysStmt2);
var_dump($returnObj2);

Sunday, March 13, 2011

install and configure Zend server Java Bridge on Linux

As far as I know, there are two active PHP-Java bridge projects. One is PHP/Java Bridge hosted on SourceForge. The other is Java bridge coming with Zend Server and Zend Server CE for linux and IBM i. It is clear that sourceForge PHP/Java bridge is based on SOAP web service. But, this make me feel it is not useful so much as it is not difficult for a PHP programmer to write SOAP client to call a SOAP service written in Java. I guess Zend Java bridge is implemented in client/server architecture too as its configuration parameters include a TCP/IP port number. I thought Zend Java Bridge is written based on JNI technology. However, it seems not true.

Anyway, the mystification of Zend Java Bridge attracts me to give it a shot. Here are simple steps about how to install and configure Zend Java Bridge.

1) Following post Installing Zend server CE on Fedora 14 and fix YUM update to install Zend Server CE on Fedora 14.

2) Running command yum search java-bridge to have output similar as below.

[root@jiaFedora14 yyjia]# yum search java-bridge
Loaded plugins: langpacks, presto, refresh-packagekit
Adding en_US to language list
updates/pkgtags | 56 kB 00:00
======================================================================== Matched: java-bridge =========================================================================
php-5.2-java-bridge-zend-server.x86_64 : Zend Java bridge
php-5.3-java-bridge-zend-server.x86_64 : Zend Java bridge
[root@jiaFedora14 yyjia]#


3) call command yum install php-5.3-java-bridge-zend-server to install Zend Java Bridge as I installed php 5.3 version on my machine.

4) call command /usr/local/zend/etc/rc.d/06jb stop and command /usr/local/zend/etc/rc.d/06jb start to start Zend Java Bridge if it is necessary. Or you can enable/disable Zend Java Bridge from Zend Server admin Web page.

5) compile following Java code into a .jar file, say jia.jar and add put it into directory /usr/local/zend/bin.

SystemPropertyList.java
package jia.blog.util.lang;

import java.util.Properties;

/**
 *
 * @author Yiyu Jia
 */
public class SystemPropertyList {

    public static Properties listSystemProperties(){
         return System.getProperties();
    }
}


6) open file /usr/local/zend/etc/watchdog-jb.ini and add jia.jar file into the CLASSPATH.

7) put below PHP code into directory, where Zend server executes php file. For example, /var/www/html.

javaInfo.php
<?php
$javaEnv = new Java("jia.blog.util.lang.SystemPropertyList");
$out = $javaEnv->listSystemProperties();
?>

List of JVM System Properties

<?php foreach($out as $key => $value) { ?> <?php } ?>
<?php echo $key; ?> <?php echo $value; ?>

8) open web browser and access php code, for example http://localhost/javaEnv.php. If you can see the list of Java system properties, it is done. Enjoy it. This Java system properties is very important for Java programmer to create java app running in Zend Java Bridge.

Note: it seems that Zend Java Bridge does not support Java class hot deployment. So, you may need to restart Java Bridge every time after you modified your java classes.

Thursday, March 10, 2011

Implementing Singleton pattern in Java and PHP shows different "static" modifers between Java and PHP

This is a quick note about the difference between Java "static" modifier and PHP "static" modifier. I investigated the different "static" modifiers in Java and PHP (static variable in PHP vs static variable in Java). Here is a quick notes that shows more difference. It is about "synchronized" and multi-threaded safe coding. Java programmer have to pay extra attention when static variables are used. However, this is not problem in PHP. It does not mean PHP is better than Java. It is just because PHP does not natively support multi-thread.

The following are two singleton pattern implementations in Java and PHP respectively. Listing both of them here can clearly show the difference between Java and PHP static variables.

Java Singleton pattern
/**
 * @author Yiyu Jia
 */
public class DBConnectionFactory {
   
    // static means there will be only one instance in one JVM.
    private static DBConnectionFactory m_connFactory = new DBConnectionFactory();

    // private means this class can not be created by "new" operator outside it.
    private DBConnectionFactory() {
        //connManagerList = new ConcurrentHashMap();
    }
    
    public static DBConnectionFactory getInstance() {

        return m_connFactory;

    }


}

To have better understand about Java memory management, singleton pattern, we can refer to this article and links inside it.



PHP singleton pattern
/**
  * @author Yiyu Jia
  */
class JiaLog
{ 
    private static $_instance;   
    private $logger;
    
    // declaring constructor to be private function.
    private function __construct() 
    {       
     $writer = new Zend_Log_Writer_Stream('path/to/logfile');     
     $this->logger = new Zend_Log($writer);     
    }

    //public static function is the way allowed to get instance
    public static function getJiaLog() 
    {
        if (!isset(self::$_instance)) {
            $c = __CLASS__;
            self::$_instance = new $c;
        }
        return self::$_instance;  
    }
    
   
    public function info($str)
    {
        $this->logger->log($str, Zend_Log::INFO);
    }   

    // Prevent users to clone the instance
    public function __clone()
    {
     trigger_error('Clone is not allowed.', E_USER_ERROR);
    }
}

Sunday, March 6, 2011

Installing Zend server CE on Fedora 14 and fix YUM update

Install Zend Server CE on Fedora 14 (SElinux diabled) is pretty easy. Here are key steps,

1) With root account privilege, go to directory /etc/yum.repos.d and create a file named as anyName.repo. The content of file is as below,


[Zend]
name=Zend Server
baseurl=http://repos.zend.com/zend-server/rpm/$basearch
enabled=1
gpgcheck=0

[Zend_noarch]
name=Zend Server - noarch
baseurl=http://repos.zend.com/zend-server/rpm/noarch
enabled=1
gpgcheck=0


2) With root privilege, running below command,
yum install zend-server-php-5.3

3) After running step 2, Zend server is installed. However, you may run into error when you run yum update. The error message is as below,

Fatal Python error: pycurl: libcurl link-time version is older than compile-time version.

To solve this, we need to do two more things to correct the system.

  1. modify file /etc/ld.so.conf.d/zend_server.conf to have below content,

    cat /etc/ld.so.conf.d/zend_server.conf
    /usr/lib64
    /usr/local/zend/lib


  2. run linux command ldconfig to build correct symbolic links.

Tuesday, February 22, 2011

PHP DB2 extension should support features like timeout checking.

I ran into very troublesome problem when I use DB2 connection from PHP to call RPG stored procedure. What happened is described in the following diagram.
  
As you can see, if calling a bad configured RPG stored procedure from PHP through DB2 extension on the same machine where Zend server and DB2 are installed, Zend Server may hang and it can not even be restarted from Zend Menu in green screen of i5/OS.

The appeared phenomenon is that QSQSRVR jobs is under MSGW status and seems the waiting status will never be broken. I am not sure which part exactly causes this. But, I think adding a time-out check mechanism in PHP DB2 extension on IBM i could be considered. The detailed discussion can be found from Zend Forums.

Monday, February 14, 2011

IBM Web Shpere MQ client for PHP on IBM i platform.

I am designing a log framework for my PHP code on IBM i. As the application will not only log some system level info but also many application level logs, I can expect that the log traffic will be crowed. In this case, I would like to let the app to throw log info into a message queue rather than to directly write into database.

However, I noticed that Zend Framework (v1.10) on IBM i only partially supports ActiveMQ as MQ client. I also find that there are at least two PHP extension in PECL to support IBM Web Sphere MQ: mqseries and SAM . However, as extensions, both of them are wrappers of under native code. So, they might have compiled libraries for Linux or MS Windows. But, there is no compiled package for IBM i platform.

So, we can see that we can not use IBM Web Sphere MQ with PHP on IBM i platform. In my case, I can not use Zend Server for IBM i and IBM Web Sphere together with Zend PHP. Therefore, using ActiveMQ on IBM i with Zend PHP on IBM will be only option (not consider other asynchronous message methods). But, I feel this is funny as I think IBM will not see ActiveMQ, which implements STOMP protocol, is used to replace Web Sphere MQ on IBM i and Zend will not see developer finally adband Zend server for IBM i and go back to linux, where more PHP vendors can compete at. As a developer, it is uncomfortable not to be able to use most nature way to finish project on IBM i.

If possible, we can put PHP engine on a Linux server and install MySQL server and DB2i storage engine on IBM i. then, PHP developer can walk around the DB2 Connect license issue and Web Sphere MQ client issue. However, if this happen, technically speaking, it will be easier for applicaton developer to shift whole application out of IBM i platform. Is this what IBM and Zend want? I guess they will not. So, I think Zend or IBM should release a PHP version Web Sphere MQ client for IBM i platform. I put my thoughts on Zend forum (link). I hope they will see it.

Friday, January 21, 2011

Did MySQL for IBM i5/OS platform die?

On Zend Forum, there is a hot discussion about MySQL announce EOL support for MySQL on IBM i. This is the link to Zend forum post. This is MySQL EOL announce. However, after reading those discussion, I feel some of them are worrying something which they do not need to worry about.

I think the EOL support only means that there will be newer version of MySQL for IBM i platform. It does not mean developer can not use existing latest version of MySQL on IBM i. The only thing missed  is that you can not BUY support from MySQL because they do not supply this service. However, will this be big issue? I do not think it is going to big problem because many people want to use MySQL because it is FREE. I think I will be happy with MySQL as long as its features are enough for my application and it is in a product quality.

So, I would like to ask people, who worry about the EOL support for MySQL on IBM i, to think about one thing. What do they want, always upgrading to latest version of MySQL or using one stable version to build their own product? Obviously, most of people's target is the second one: build their own application on top of free MySQL RDBMS. Therefore, I would like to say MySQL does not have its EOL on IBM i. Developers can still use it as long as they are satisfied with its quality and features.

I am interesting in MySQL on IBM i is because I am looking for a way to walk around the DB2 Connect license fee issue. To remotely connect to a IBM i DB2, developer need to buy DB2 Connect license from IBM if they are not using free type 4 JDBC library like jt400. Therefore, I am thinking that let PHP script to remotely connect to MySQL server with DB2i storage engine might be a good way to walk around this license issue. With this solution, PHP can write and read data which is stored in DB2. And the data can be subsequently accessed from DB2 side like RPG programm. But, the limitation will be that developer can only write stored procedure in MySQL and this stored procedure can be remotely accessed by PHP through MySQL interface.

Monday, January 10, 2011

Installing activeMQ on IBM i5 V5R4

The project I am working on is written in PHP. Since it is a B2B web service, I want my application to write down both system level log and application level log as much as possible. Then, somebody can analyze the log when they want to.

However, as well known, an I/O operation is a time consuming operation. Obviously, I do not want this logging function will significantly slow down my application. Therefore, I design a asynchronous model to write logs. In order to be asynchronous, I have two choices. The first is multi-threaded. The second is messaging queue. Since PHP does not have built-in support for multi-thread and PHP is stateless, I choose Messaging Queue. I used to lead on migrating from Sonic MQ to ActiveMQ for a ETL engine project. So, I decide to give it a try on IBM i i5 V5R4 platform.

On IBM i i5 V5R4 platform, I have JDK 1.5 32bit, which is IBM J9 VM. Below is the steps I install activeMQ on IBM i5/OS V5R4,

1) run command call qp2term to open a i5/OS PASE terminal session.

2) run java -version to check the JDK version.

3) run export JAVA_HOME=/QOpenSys/QIBM/ProdData/JavaVM/jdk50/32bit to set this session's JAVA_HOME to point to JDK1.5 . or, call command CHGENVVAR ENVVAR(JAVA_HOME) VALUE('/QOpenSys/QIBM/ProdData/JavaVM/jdk50/32bit') to modify the JAVA_HOME environment if i have not in PASE environment. or use ADDENVVAR to add the environment.

4) run java -version to check the JDK version again to make sure your using JDK 1.5 now.

5) Go to http://activemq.apache.org/ and download activeMQ distribution for Unix/Linux/Cygwin platform. I downloaded version 5.4.2 .

6) using 7zip to unzip the file to be a TAR file as I can not use -z option with tar command in PASE environment on i5/OS.

7) copying the tar file under my home directory on i5/OS via IFS.

8) running command tar -xvf apache-activemq-5.4.2.tar

9) cd into directory "apache-activemq-5.4.2" and run command ./bin/activemq to start up activemq with default configuration.

10) Since I can not control i5/OS and the PASE terminal emulator might has problem with character schema used by JDK in default. I choose to test this activemq instance from my PC workstation.

11) Download and install activemq zip format distribution.

12) set the JAVA_HOME environment properly from either Windows system environment variable setting or adding set JAVA_HOME=%your jdk home directory% into BATCH files.

13) Download and install apache ANT and add ANT bin directory into Windows PATH environment.

14) In windows command prompt window, go to activemq example directory and run command ant producer -Durl=tcp://your_i5_host:11616 to send sample msg into activemq testing channel.

15) In windows command prompt window, go to activemq example directory and run command ant consumer -Durl=tcp://your_i5_host:11616 to consume sample msg inside activemq testing channel.

After the last two steps is successful, I know I can use activeMQ on i5/OS. Although this is not a installation for product environment, it shows me how to install activeMQ under my home directory as developing environment.

Sunday, December 12, 2010

Zend Framework resource plug in and avoid using Zend_Application_Resource_Multidb in wrong way

Personally, I do not think it has significant advantage to use configuration file (application.ini) from Zend Framework because 1) I do not see big difference between PHP script file and plain text configuration file in PHP enviroment. Probably, placing configuration directly in PHP script is better in terms of performance, easy maintenance and flexible. 2) the cost of following design of Zend Framework, for example resource plugin, is that programmer has to be very careful about each components' life cycle in the system. In other words, the programmer has to understand how the thing happens insight.

Here, I have an example. I was given an authentication library as resource plugin for Zend Framework. It asks for multidb resource configuration in application.ini. It has two databases resources. The second one gets the database connection confidential parameters by calling through the first one (default db).

After checking the source code of Zend Framework. We can see that bootstrap will initialize all database adapters from multidb resource specified in application.ini. So, here is the problem. What will happen to the second database connection in multidb when bootstrap tried to initialize it without properly database connection parameters? Fortunately, Zend Framework does not really call php database connection function ( in my case db2_(p)connect) when the DB adapter is initialized. Database connection function call is only called when php script tries to get connection from DB adapter.

However, it is really confusing to specify wrong connection parameters in application.ini as multidb plugin. Then, correcting parameters in some place else. Using multidb as resource plugin might be good practice when multiple database adapters are needed in multiple places in the code and all connection parameters are known. Otherwise, it is neat to create database connection when it is needed.

Simple should be always one of main considerations of software design. Especially, for an interpret language like PHP, this could be more important.

Friday, November 5, 2010

A simple tutorial about creating Zend_Rest_Server based RESTful service.

It seems that RESTful WS is attracting more people to consider as RPC solution. Compared with SOAP based Web Service, RESTful has its advantage and disadvantage. RESTful WS is declared to be more scalability as it exactly maps HTTP methods  POST, GET, PUT, DELETE as a CRUD (Create, Request, Update, Delete) operations. So, if we design our RESTful WS as stateless, it could be more scalable in a cluster farm. It can get benefit from Cache mechanism of HTTP (limited to HTTP GET method configuration on proxy server in most time). However, it could be problem or ask for cost if we do not want the result to be cached. Furthermore, we can not always assume client Web browser has cache enabled. So, RESTful is not always right choice. Especially, it is not good choice when we develop an enterprise application which ask for complex data structure delivered between sub systems and it does not have extremely large volume of the concurrent accessing.

I will compose another post to describe my comparison about SOAP WS and RESTful WS and JSON-RPC. Here, I will show a simple demo about how to create Zend_Rest_Server based RESTful WS in Zend Studio. Zend_Rest_Server is not perfect. For instances, it can not work together with Zend_Action_Router_Route. It also asked for calling function by put "method=functionName" in requesting URL after the "?". This make some guys think it is not RESTful WS as some person said it is not good design. But, I think it is not wrong design at least.  Below is source for simple ZF based RESTful WS.
  1. Create a new ZF project in Zend Studio and name it as jiaRESTfulWS.
  2. Add autoloaderNamespaces[] = "Jia_" in application.ini to allow Zend Autoloader load Jia_* classes.
  3. Creating a action class DummyController under directory /application/controllers. 
  4. creating a function restAction() in DummyController .
  5. Creating a Jia_Hello class with sayHello($name) function under /library/Jia directory.
It is done. You need to pay attention on how to specify web service URI in the code if you use different project name and function names. Or, you might want to add alias in your apache httpd configuration file to simplify the URL. On my machine, this demo RESTful WS can be accessed with following URL: http://localhost/jiaRESTfulWS/public/index.php/Dummy/rest?method=sayHello&name=jia . See key source code as below,

Jia_Hello class
/**
 * This class contains function which will be used by Web service caller.
 * All business logics will be implented or called in these functions.
 * 
 * @author Yiyu Jia
 *
 */
class Jia_Hello {

 /**
  * 
  * @param string $name
  * @return string
  * 
  */
 public function sayHello($name){
  return "hello ".$name;
 }
}


DummyController class
/**
 * This class includes one function restAction(), wich has Zend_Rest_Server initialized.
 * However, you can only use URI with "?" like this "/rest?method=sayHello&name=jia". You 
 * can not have URI like "/rest/name/jia"
 * 
 * @author yiyu
 *
 */
class DummyController extends Zend_Controller_Action
{
 /**
  *  action named as rest.
  */
 public function restAction() {
  
  // disable layouts and renderers
  $this->getHelper ( 'viewRenderer' )->setNoRender ( true );
  
  // initialize REST server
  $server = new Zend_Rest_Server();
  // set REST service class
  $server->setClass ( 'Jia_Hello' ); 
    
  // handle request
  $server->handle ();
 
 }
 
}

Zend Studio 7.2 project file can be downloaded here. Also, I do not recommend to use Zend_Rest_Server for developing RESTful WS as I think it is old and uncompleted class. Zend_Rest_Route should be a better choice to make RESTful Web Service in PHP. Here is a simple tutorial about how to use Zend_Rest_Route and Zend_Rest_Controller to create RESTful Web Service. Creating RESTful service with Zend_Rest_Route and Zend_Rest_Controller

Saturday, October 30, 2010

A discussion about asynchronous programming in PHP and further

I read an article about asynchronous programming in PHP. It declares that lacking asynchronous programming is not limitation from PHP language. However, I think this is obviously the limitation of PHP.

Lacking of multi-thread features is the source of the limitation. PHP programmers have argued that they can use named pipe, node.js, libevent, Curl, Zend_Job, and other process control extensions to implement asynchronous functions in PHP. However, these methods are not core PHP feature. Therefore, there is no guarantee that these functions can be run on all platforms on which core PHP can run. For example, I wonder whether libevent can run on IBM i platform or not. Zend Server for IBM i supports Zend_Job. But it is not in Zend Server CE, which is free. Also, some extensions like PCNTL seems a solution based on multi process with shared memory. It is a inter-process implementation. Multithreading is a inner process implementation.

This limitation of PHP is because of the way of running PHP script too. PHP is known that it has less memory leak problem. This is not surprised as each PHP script is loaded into memory only when it need to be executed. After it is executed, it is flushed out of memory. Of course, PHP has no memory leak as it has no memory at all.This is because PHP inherits from perl as CGI programming language. Somebody will argue that PHP actually has optimizers and extensions like memcache. These make PHP looks like have some memory. However, optimizer is for caching operation code. memcache is for caching some data as a persistent storage. They can not make PHP to have real memory.

Since PHP has no memory, core PHP has no function like PipedInputStream, PipedOutputStream, and multi thread etc. As I presented in an old post, its static modifier means different life scope than other languages do. So, lacking of asynchronous programming feature is the limitation from PHP itself. It is confusing to discuss PHP lacks asynchronous feature and deny it is limitation from PHP language itself.

Also, in servlet world, people has been interested in changing "request per thread" architecture because of the challenge from multiplied Ajax calling from browser side. Leading by Jetty, both Jetty and Tomcat 7.0 has implemented asynchronous servlet API already. I will deeply investigate whether PHP is facing same challenge or not. Or, with Fastcgi, PHP does not need to worry about this at all.

Tuesday, September 28, 2010

static variable in PHP vs static variable in Java

PHP is evolving to be a Object Oriented language. As a java programmer and PHP programmer, I like to compare PHP with Java. In this post, I am going to write down my comparison about "static" modifier in PHP and Java.

PHP and Java as they have different architecture for running time environment. I feel it is necessary point out the difference between PHP static and Java static. We can investigate this from two different aspects at least: static variable scope and static variable access.

Firstly, let's see the difference about static variable scope. For Java, a static variable will survive throughout the whole life when JVM is running or when class is unloaded using some techniques. That means, once the static variable is used, it will exist in memory as long as the java application is running. And, there is only one copy of static variable in memory (in one Java class loader's scope in a JVM process). For PHP, the thing is different as PHP has no memory. That means all PHP code will be flushed out after php scripts (including all included and required php script files). So, the variables, which is even declared as "static" or "Global", will be destroyed . A PHP variable can not survive through two different script executions. Other thing we need to pay attention to is that programmer is not supposed to assign a reference to a static variable.

Secondly, let's see some difference about how to access static variables in PHP and Java.  Both Java and PHP has concepts about "class"  and "instance of class" now. A "className" is used as class in code. A "new className()" is used as instance (object) of class in code. But, I noticed a difference of calling static member in class between PHP and Java. In Java, a static variable can be referred through a instance of class though it is not encouraged. In PHP, it is not allowed to do so according to my test. Below are code snippet,

 Java code
/**
 *
 * @author Yiyu Jia
 */
public class Main {

    public static String dummy = "dummy";

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        Main foo = new Main();
        //I can access the static variable through class instance
        //although this is not encouraged.
        System.out.println(foo.dummy); 
    }

}

 PHP code
class DummyClass
{
    static $jia = 'yiyu';

    function testStatic()
    {
     print(self::$jia);
     echo $this->jia; //error. Not allowed in PHP.
    }
}

Java and PHP has totally different run time environment architecture. I am going to find a good way to present the difference later.

For deeper understand about PHP static modifier, below URLs are very helpful,

1)Static keyword: http://php.net/manual/en/language.oop5.static.php


2)Variable scope: http://php.net/manual/en/language.variables.scope.php


3)Something important after PHP became a OOP: http://www.php.net/manual/en/language.references.return.php