Skip navigation.

JL空间

contact to me: liuping.james#gmail.com (use @ replace #)

How to write PHP MVC Framework

, ,

Learning process:

1: u should know what isMVC

2: How to write MVC
Model
View
Controller

3: Don't write MVC Framework when u don't know it and don't need it.

4: MVC Framework isn't Project's EveryThing. It is just Framework and it is every Framework only fit for something, not all.

msn robot

,

Maybe someone wanna know.

1: msn function robot which can do msn work.
i used "http://jmsn.sourceforge.net/"
(Chinese people can find it http://www.pconline.com.cn/pcedu/empolder/gj/java/0412/512503_3.html)

2: analyzer. You should analyzer msn's word when u receive it.

3: search. return Response when finished search.

2 and 3, i used solr and analyzer use CJKAnalyzer.

Today is my birthday.

4.14, today is my birthday.

Many people of bbs which i love say birthday to me, im very happy.

Thks for everyone who love me and hate me.

I will do my best.

FreeBSD6,PHP connect ms sql server 2000

, ,

i think it is the simplest way to fix it.

first install php5 and php5-extensions

Install with php5-extensions, u must check mssql(default it is uncheck).

Notice install process, u will it will install freetds(google it).

Install ok...you should do

cp /usr/local/etc/freebsd.conf.dist /usr/local/etc/freebsd.conf
chmod +r /usr/local/etc/freebsd.conf
ee freebsd.conf
delete # with [MyServer2k] and its sub item. host changed to sql server's ip.

php code like:

mssql_connect('MyServer2k', $dbuser, $dbpass);

mssql function u find it in php handbook.

and u should add line to MyServer2k,,it will help me to solve chinese word show.

client charset = utf-8.


Unix shell programming

,

Deep in cache_lite

if u don't know what cache_lite, please google it.

cache_lite source code(we can use it out of this class)

cache_lite
Cache_lite//getOption
clean//clean cache
extendLife//extend the life of avalid cache file
get//if cache is available return it
getMemoryCachingState//load the state of the caching memory array from a given file cache
lastModified//return the cache last modification time
raiseError//trigger a pear error
remove//remove a cache file
save//save some data in a cache file
saveMemoryCachingState//save the state of the caching memory array into a cache file cache
setLifeTime//set a new life time
setOption//generic way to set a cache_lite option
setToDebug//when an error is found, the script will stop and the message will be displayed(in debug mode)


we can find import function: getMemoryCachingState, saveMemoryState, save, get.

getMemoryCachingState, saveMemoeyState means what? php can define memory space like c? no.
let's see its source code.
    function saveMemoryCachingState($id, $group = 'default')
    {
        if ($this->_caching) {
            $array = array(
                'counter' => $this->_memoryCachingCounter,
                'array' => $this->_memoryCachingState
            );
            $data = serialize($array);
            $this->save($data, $id, $group);
        }
    }
    function save($data, $id = NULL, $group = 'default')
    {
        if ($this->_caching) {
            if ($this->_automaticSerialization) {
                $data = serialize($data);
            }
            if (isset($id)) {
                $this->_setFileName($id, $group);
            }
            if ($this->_memoryCaching) {
                $this->_memoryCacheAdd($data);
                if ($this->_onlyMemoryCaching) {
                    return true;
                }
            }
            if ($this->_automaticCleaningFactor>0) {
                $rand = rand(1, $this->_automaticCleaningFactor);
                if ($rand==1) {
                    $this->clean(false, 'old');
                }
            }
            if ($this->_writeControl) {
                $res = $this->_writeAndControl($data);
                if (is_bool($res)) {
                    if ($res) {
                        return true;  
                    }
                    // if $res if false, we need to invalidate the cache
                    @touch($this->_file, time() - 2*abs($this->_lifeTime));
                    return false;
                }            
            } else {
                $res = $this->_write($data);
            }
            if (is_object($res)) {
        // $res is a PEAR_Error object 
                if (!($this->_errorHandlingAPIBreak)) {   
                return false; // we return false (old API)
            }
        }
            return $res;
        }
        return false;
    }
    function _memoryCacheAdd($data)
    {
        [B]$this->_memoryCachingArray[$this->_file] = $data;[/B]
        if ($this->_memoryCachingCounter >= $this->_memoryCachingLimit) {
            list($key, ) = each($this->_memoryCachingArray);
            unset($this->_memoryCachingArray[$key]);
        } else {
            $this->_memoryCachingCounter = $this->_memoryCachingCounter + 1;
        }
    }



we can find it use array like global array, memoryCache is just Cache_lite public array.


we must know hash(google "data structures") when we analyze set, get function.
    function _write($data)
    {
        if ($this->_hashedDirectoryLevel > 0) {
            $hash = md5($this->_fileName);
            $root = $this->_cacheDir;
            for ($i=0 ; $i<$this->_hashedDirectoryLevel ; $i++) {
                $root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/';
                if (!(@is_dir($root))) {
                    @mkdir($root, $this->_hashedDirectoryUmask);
                }
            }
        }
        $fp = @fopen($this->_file, "wb");
        if ($fp) {
            if ($this->_fileLocking) @flock($fp, LOCK_EX);
            if ($this->_readControl) {
                @fwrite($fp, $this->_hash($data, $this->_readControlType), 32);
            }
            $len = strlen($data);
            @fwrite($fp, $data, $len);
            if ($this->_fileLocking) @flock($fp, LOCK_UN);
            @fclose($fp);
            return true;
        }      
        return $this->raiseError('Cache_Lite : Unable to write cache file : '.$this->_file, -1);
    }

cache_lite use some string(hash string) to set directory when use hashedDirectoryLevel(u can find it in cache_lite document) .

if we know how to store it, and it is easy how to get it.
    function _read()
    {
        $fp = @fopen($this->_file, "rb");
        if ($this->_fileLocking) @flock($fp, LOCK_SH);
        if ($fp) {
            clearstatcache();
            $length = @filesize($this->_file);
            $mqr = get_magic_quotes_runtime();
            set_magic_quotes_runtime(0);
            if ($this->_readControl) {
                $hashControl = @fread($fp, 32);
                $length = $length - 32;
            } 
            if ($length) {
                $data = @fread($fp, $length);
            } else {
                $data = '';
            }
            set_magic_quotes_runtime($mqr);
            if ($this->_fileLocking) @flock($fp, LOCK_UN);
            @fclose($fp);
            if ($this->_readControl) {
                $hashData = $this->_hash($data, $this->_readControlType);
                if ($hashData != $hashControl) {
                    if (!(is_null($this->_lifeTime))) {
                        @touch($this->_file, time() - 2*abs($this->_lifeTime)); 
                    } else {
                        @unlink($this->_file);
                    }
                    return false;
                }
            }
            return $data;
        }
        return $this->raiseError('Cache_Lite : Unable to read cache !', -2); 
    }



Cache_lite is a small file cache, and it only fit for small system, test system and only php system.

Memcached is a high-performance, distributed memory object caching system。
It fit for any system, and it not only fit for php system.


Write by JL
2007-2-21

improving php performance on apache

, ,

article from: http://www.whenpenguinsattack.com/2006/01/24/improving-php-performance-on-apache/

Apache is available on both Unix and Windows. It is the most popular web server in the world. Apache 1.3 uses a pre-forking model for web serving. When Apache starts up, it creates multiple child processes that handle HTTP requests. The initial parent process acts like a guardian angel, making sure that all the child processes are working properly and coordinating everything. As more HTTP requests come in, more child processes are spawned to process them. As the HTTP requests slow down, the parent will kill the idle child processes, freeing up resources for other processes. The beauty of this scheme is that it makes Apache extremely robust. Even if a child process crashes, the parent and the other child processes are insulated from the crashing child.
The pre-forking model is not as fast as some other possible designs, but to me that it is “much ado about nothing” on a server serving PHP scripts because other bottlenecks will kick in long before Apache performance issues become significant. The robustness and reliability of Apache is more important.

Apache 2.0 offers operation in multi-threaded mode. My benchmarks indicate there is little performance advantage in this mode. Also be warned that many PHP extensions are not compatible (e.g. GD and IMAP). Tested with Apache 2.0.47.
Apache is configured using the httpd.conf file. The following parameters are particularly important in configuring child processes:

MaxClients : default: 256
The maximum number of child processes to create. The default means that up to 256 HTTP requests can be handled concurrently. Any further connection requests are queued.

StartServers: default: 5
The number of child processes to create on startup.

MinSpareServers: default:5
The number of idle child processes that should be created. If the number of idle child processes falls to less than this number, 1 child is created initially, then 2 after another second, then 4 after another second, and so forth till 32 children are created per second.

MaxSpareServers: default:10
If more than this number of child processes are alive, then these extra processes will be terminated.

MaxRequestsPerChild: default: 0
Sets the number of HTTP requests a child can handle before terminating. Setting to 0 means never terminate. Set this to a value to between 100 to 10000 if you suspect memory leaks are occurring, or to free under-utilized resources

For large sites, values close to the following might be better:

MinSpareServers 32
MaxSpareServers 64

Apache on Windows behaves differently. Instead of using child processes, Apache uses threads. The above parameters are not used. Instead we have one parameter: ThreadsPerChild which defaults to 50. This parameter sets the number of threads that can be spawned by Apache. As there is only one child process in the Windows version, the default setting of 50 means only 50 concurrent HTTP requests can be handled. For web servers experiencing higher traffic, increase this value to between 256 to 1024.

Other useful performance parameters you can change include:

SendBufferSize: Set to OS default
Determines the size of the output buffer (in bytes) used in TCP/IP connections. This is primarily useful for congested or slow networks when packets need to be buffered; you then set this parameter close to the size of the largest file normally downloaded. One TCP/IP buffer will be created per client connection.

KeepAlive [onoff] default:On
In the original HTTP specification, every HTTP request had to establish a separate connection to the server. To reduce the overhead of frequent connects, the keep-alive header was developed. Keep-alives tells the server to reuse the same socket connection for multiple HTTP requests.

If a separate dedicated web server serves all images, you can disable this option. This technique can substantially improve resource utilization.

KeepAliveTimeout:default:15
The number of seconds to keep the socket connection alive. This time includes the generation of content by the server and acknowledgements by the client. If the client does not respond in time, it must make a new connection.

This value should be kept low as the socket will be idle for extended periods otherwise.

MaxKeepAliveRequests: default:100
Socket connections will be terminated when the number of requests set by MaxKeepAliveRequests is reached. Keep this to a high value below MaxClients or ThreadsPerChild.

TimeOut: default:300
Disconnect when idle time exceeds this value. You can set this value lower if your clients have low latencies.

LimitRequestBody: default:0
Maximum size of a PUT or POST. O means there is no limit.

If you do not require DNS lookups and you are not using the htaccess file to configure Apache settings for individual directories you can set:

# disable DNS lookups: PHP scripts only get the IP address
HostnameLookups off

# disable htaccess checks

<Directory />

AllowOverride none

</Directory>

If you are not worried about the directory security when accessing symbolic links, turn on FollowSymLinks and turn off SymLinksIfOwnerMatch to prevent additional lstat() system calls from being made:

Options FollowSymLinks

#Options SymLinksIfOwnerMatch

[zz] improving php execution speed in windows with php.ini

,

article from: http://www.whenpenguinsattack.com/2006/02/02/improving-php-execution-speed-in-windows-with-phpini/

adding the following two lines to php.ini can make your php scripts run run faster and also save you in bandwidth.

zlib.output_compression = On
zlib.output_compression_level = level

level can be from 1-9. This is a tradeoff between speed and size. The higer compression levels create files that are smaller in size (which will save you in bandwidth), but they take more processing time to de-compress/compress. Most web-browsers support this standard. It is best to choose different numbers to find out which one will work best for your server.

using java and mysql

,

article from: http://www.whenpenguinsattack.com/2006/02/10/using-java-and-mysql/


using java and mysql
February 10th, 2006 | Category: mysql, java

by Paul DuBois

You can write MySQL applications in a variety of languages. The languages that most people use with MySQL are PHP and Perl, but a sometimes overlooked option is the MySQL Connector/J driver, which allows you to develop Java applications that interact with your MySQL server.
MySQL Connector/J works within the framework of the Java JDBC interface, an API that allows Java programs to use database servers in a portable way. JDBC is based on an approach similar to that used in the design of Perl and Ruby DBI modules, Python’s DB-API module, and

PHP’s PEAR::DB class. This approach uses a two-tier architecture:
The top level is visible to application programs and presents an abstract interface for connecting to and using database engines. The application interface does not depend on details specific to particular engines.

The lower level consists of drivers for individual database engines. Each driver handles the details necessary to map the abstract application interface onto operations that a specific engine will understand.The JDBC interface allows developers to write applications that can be used with different databases with a minimum of porting effort. Once a driver for a given server engine is installed, JDBC applications can communicate with any server of that type. By using MySQL Connector/J, your Java programs can access MySQL databases.

Note: MySQL Connector/J is the successor to the MM.MySQL driver. If you have JDBC programs written for MM.MySQL, they should work with MySQL Connector/J as well, although you may want to update the driver class name used in your programs. Just replace instances of org.gjt.mm.mysql in your Java source files with com.mysql.jdbc and recompile.

Preliminary Requirements

To use Java applications with MySQL, you may need to install some additional software:
If you want to compile and run Java programs, you’ll need a Java compiler (such as javac or jikes) and a runtime environment. If these are not already installed on your system, you can get them by obtaining a Java Software Development Kit (SDK) from java.sun.com.

If you want only to run precompiled applications, no compiler is necessary, but you’ll still need a Java Runtime Environment (JRE). This too may be obtained from java.sun.com.This article assumes that you’ll write and compile your own programs, and thus that you have a Java SDK installed. Once you compile a Java program, however, you can deploy it to other machines, even ones that have only a runtime environment. This works even in heterogenous installations, because Java is platform-independent. Applications compiled on one platform can be expected to work on other platforms. For example, you can develop on a Linux box and deploy on Windows

Connecting to the MySQL Server

To connect to the MySQL server, register the JDBC driver you plan to use, then invoke its getConnection() method. The following short program, Connect.java, shows how to connect to and disconnect from a server running on the local host. It accesses a database named test, using a MySQL account with a user name and password of testuser and testpass: import java.sql.*;

public class Connect
{
public static void main (String[] args)
{
Connection conn = null;
try
{
String userName = “testuser”;
String password = “testpass”;
String url = “jdbc:mysql://localhost/test”;
Class.forName (”com.mysql.jdbc.Driver”).newInstance ();
conn = DriverManager.getConnection (url, userName, password);
System.out.println (”Database connection established”);
}
catch (Exception e)
{
System.err.println (”Cannot connect to database server”);
}
finally
{
if (conn != null)
{
try
{
conn.close ();
System.out.println (”Database connection terminated”);
}
catch (Exception e) { /* ignore close errors */ }
}
}
}
}

Compile Connect.java to produce a class file Connect.class that contains executable Java code: % javac Connect.java
Then invoke the class file as follows and it should connect to and disconnect from your MySQL server: % java Connect
Database connection established
Database connection terminated
If you have trouble compiling Connect.java, double check that you have a Java Software Development Kit installed and make sure that the MySQL Connector/J driver is listed in your CLASSPATH environment variable.

The arguments to getConnection() are the connection URL and the user name and password of
a MySQL account. As illustrated by Connect.java, JDBC URLs for MySQL consist of jdbc:mysql:// followed by the name of the MySQL server host and the database name. An alternate syntax for specifying the user and password is to add them as parameters to the end of the connection URL: jdbc:mysql://localhost/test?user=testuser&password=testpass
When you specify a URL using this second format, getConnection() requires only one argument.

For example, the code for connecting to the MySQL server in Connect.java could have been written like this: String userName = “testuser”;
String password = “testpass”;
String url = “jdbc:mysql://localhost/test?user=”
+ userName
+ “&password=”
+ password;
Class.forName (”com.mysql.jdbc.Driver”).newInstance ();
conn = DriverManager.getConnection (url);

getConnect() returns a Connection object that may be used to interact with MySQL by issuing queries and retrieving their results. (The next section describes how to do this.) When you’re done with the connection, invoke its close() method to disconnect from the MySQL server.

To increase the portability of your applications, you can store the connection parameters (host, database, user name, and password) in a Java properties file and read the properties at runtime. Then they need not be listed in the program itself. This allows you to change the server to which the program connects by editing the properties file, rather than by having to recompile the program.

Issuing Queries

To process SQL statements in a JDBC-based application, create a Statement object from your Connection object. Statement objects support an executeUpdate() method for issuing queries that modify the database and return no result set, and an executeQuery() method for queries that do return a result set. The query-processing examples in this article use the following table, animal, which contains an integer id column and two string columns, name and category: CREATE TABLE animal
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id),
name CHAR(40),
category CHAR(40)
)
id is an AUTO_INCREMENT column, so MySQL automatically assigns successive values 1, 2, 3, … as records are added to the table.
Issuing Queries That Return No Result Set
The following example obtains a Statement object from the Connection object, then uses it to create and populate the animal table. DROP TABLE, CREATE TABLE, and INSERT all are statements that modify the database, so executeUpdate() is the appropriate method for issuing them:

Statement s = conn.createStatement ();
int count;
s.executeUpdate (”DROP TABLE IF EXISTS animal”);
s.executeUpdate (
“CREATE TABLE animal (”
+ “id INT UNSIGNED NOT NULL AUTO_INCREMENT,”
+ “PRIMARY KEY (id),”
+ “name CHAR(40), category CHAR(40))”);
count = s.executeUpdate (
“INSERT INTO animal (name, category)”
+ ” VALUES”
+ “(’snake’, ‘reptile’),”
+ “(’frog’, ‘amphibian’),”
+ “(’tuna’, ‘fish’),”
+ “(’racoon’, ‘mammal’)”);
s.close ();
System.out.println (count + ” rows were inserted”);
The executeUpdate() method returns the number of rows affected by a query. As shown above, the count is used to report how many rows the INSERT statement added to the animal table.

A Statement object may be used to issue several queries. When you’re done with it, invoke its close() method to dispose of the object and free any resources associated with it

Issuing Queries That Return a Result Set

For statements such as SELECT queries that retrieve information from the database, use executeQuery(). After calling this method, create a ResultSet object and use it to iterate through the rows returned by your query. The following example shows one way to retrieve the contents of the animal table:

Statement s = conn.createStatement ();
s.executeQuery (”SELECT id, name, category FROM animal”);
ResultSet rs = s.getResultSet ();

int count = 0;
while (rs.next ())
{
int idVal = rs.getInt (”id”);
String nameVal = rs.getString (”name”);
String catVal = rs.getString (”category”);
System.out.println (
“id = ” + idVal
+ “, name = ” + nameVal
+ “, category = ” + catVal);
++count;
}
rs.close ();
s.close ();

System.out.println (count + ” rows were retrieved”);

executeQuery() does not return a row count, so if you want to know how many rows a result set contains, you should count them yourself as you fetch them.
To obtain the column values from each row, invoke getXXX() methods that match the column data types. The getInt() and getString() methods used in the preceding example return integer and string values. As the example shows, these methods may be called using the name of a result set column. You can also fetch values by position. For the result set retrieved by the SELECT query in the example, id, name, and category are at column positions 1, 2 and 3 and thus could have been obtained like this:

int idVal = rs.getInt (1);
String nameVal = rs.getString (2);
String catVal = rs.getString (3);

ResultSet objects, like Statement objects, should be closed when you’re done with them.

To check whether or not a column value is NULL, invoke the result set object’s wasNull() method after fetching the value. For example, you could check for a NULL value in the name column like this: String nameVal = rs.getString (”name”);

if (rs.wasNull ())
nameVal = “(no name available)”;

Using Placeholders

Sometimes it’s necessary to construct queries from values containing characters that require special treatment. For example, in queries, string values are written enclosed within quotes, but any quote characters in the string itself should be doubled or escaped with a backslash to avoid creating malformed SQL. In this case, it’s much easier to let JDBC handle the escaping for you, rather than fooling around trying to do so yourself. To use this approach, create a different kind of statement (a PreparedStatement), and refer to the data values in the query string by means of placeholder characters. Then tell JDBC to bind the data values to the placeholders and it will handle any special characters automatically.

Suppose you have two variables nameVal and catVal from which you want to create a new record in the animal table. To do so without regard to whether or not the values contain special characters, issue the query like this:

PreparedStatement s;
s = conn.prepareStatement (
“INSERT INTO animal (name, category) VALUES(?,?)”);
s.setString (1, nameVal);
s.setString (2, catVal);
int count = s.executeUpdate ();
s.close ();

System.out.println (count + ” rows were inserted”);
The ‘?’ characters in the query string act as placeholders–special markers indicating where data values should be placed. The setString() method takes a placeholder position and a string value and binds the value to the appropriate placeholder, performing any special-character escaping that may be necessary. The method you use to bind a value depends on the data type. For example, setString() binds string values and setInt() binds integer values.

Error Handling

If you want to trap errors, execute your JDBC operations within a try block and use an exception handler to display information about the cause of any problems that occur. JDBC provides getMessage() and getErrorCode() methods that may be invoked when an exception occurs to obtain the error message and the numeric error code. The following example deliberately issues a malformed query. When it runs, the executeQuery() method fails and raises an exception that is handled in the catch block: try
{
Statement s = conn.createStatement ();
s.executeQuery (”XYZ”); // issue invalid query
s.close ();
}
catch (SQLException e)
{
System.err.println (”Error message: ” + e.getMessage ());
System.err.println (”Error number: ” + e.getErrorCode ());
}

[zz]Tuning IIS for PHP

,

article from: http://www.whenpenguinsattack.com/2006/07/04/tuning-iis-for-php/

IIS is a multi-threaded web server available on Windows NT and 2000. From the Internet Services Manager, it is possible to tune the following parameters:

Performance Tuning based on the number of hits per day: Determines how much memory to preallocate for IIS. (Performance Tab).

Bandwidth throttling: Controls the bandwidth per second allocated per web site. (Performance Tab).

Process throttling: Controls the CPU% available per Web site. (Performance Tab).

Timeout: Default is 900 seconds. Set to a lower value on a Local Area Network. (Web Site Tab).

HTTP Compression: In IIS 6, you can compress dynamic pages, html and images. Can be configured to cache compressed static html and images. By default compression is off.

HTTP compression has to be enabled for the entire physical server. To turn it on open the IIS console, right-click on the server (not any of the subsites, but the server in the left-hand pane), and get Properties. Click on the Service tab, and select “Compress application files” to compress dynamic content, and “Compress static files” to compress static content.

You can also configure the default isolation level of your web site. In the Home Directory tab under Application Protection, you can define your level of isolation. A highly isolated web site will run slower because it is running as a separate process from IIS, while running web site in the IIS process is the fastest but will bring down the server if there are serious bugs in the web site code. Currently I recommend running PHP web sites using CGI, or using ISAPI with Application Protection set to high.

You can also use regedit.exe to modify following IIS 5 registry settings stored at the following location:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Inetinfo\Parameters
MemCacheSize: Sets the amount of memory that IIS will use for its file cache. By default IIS will use 50% of available memory. Increase if IIS is the only application on the server. Value is in megabytes.

MaxCachedFileSize: Determines the maximum size of a file cached in the file cache in bytes. Default is 262,144 (256K).

ObjectCacheTTL: Sets the length of time (in milliseconds) that objects in the cache are held in memory. Default is 30,000 milliseconds (30 seconds).

MaxPoolThreads: Sets the number of pool threads to create per processor. Determines how many CGI applications can run concurrently. Default is 4. Increase this value if you are using PHP in CGI mode.

ListenBackLog: Specifies the maximum number of active Keep Alive connections that IIS maintains in the connection queue. Default is 15, and should be increased to the number of concurrent connections you want to support. Maximum is 250.

If the settings are missing from this registry location, the defaults are being used.

High Performance on Windows: IIS and FastCGI

After much testing, I find that the best PHP performance on Windows is offered by using IIS with FastCGI. CGI is a protocol for calling external programs from a web server. It is not very fast because CGI programs are terminated after every page request. FastCGI modifies this protocol for high performance, by making the CGI program persist after a page request, and reusing the same CGI program when a new page request comes in.

As the installation of FastCGI with IIS is complicated, you should use the EasyWindows PHP Installer. This will install PHP, FastCGI and Turck MMCache for the best performance possible. This installer can also install PHP for Apache 1.3/2.0.
November 2009
S M T W T F S
October 2009December 2009
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30