SoFunction
Updated on 2025-04-09

PHP's treasure house directory-PEAR


You may be a veteran of PHP and have written a lot of great code. But if you are going to add them to your current project now, is it a bit difficult? Your friend wants to use your code as a module in his project, but you find that you use a completely different coding style to get him used, and it’s even better to rewrite one!
Please follow me and write your PHP program using the PEAR standard. Your program will have greater vitality. Your program and code will be easily integrated with other experts' codes. PEAR will make PHP generate higher energy just like CPAN for PERL.

What is PEAR
PEAR is the abbreviation of the PHP Extension and Application Repository. It is a code repository for PHP extensions and applications. Simply put, PHP is PHP's CPAN.

Why use PEAR?
PHP is a very excellent scripting language, concise and efficient. With the release of 4.0, more and more people use it to develop dynamic websites. It can be said that PHP has become one of the best INTERNET development languages, especially for website developers who need to develop small and medium-sized commercial applications quickly and efficiently. PHP is its preferred language. However, with the increasing number of PHP applications, there is a lack of unified standards and effective management for these applications. Therefore, it is difficult for the PHP community to share each other's code and applications as conveniently as people in the PERL community, because PHP lacks a unified code base like CPAN to classify and manage application code modules (people who are familiar with PERL know that CPAN is a huge PERL extension module repository. The application modules written can be placed under the appropriate classification directory under CPAN, and others can easily reuse it. Of course, you also need to follow the guidelines when writing application modules.)

For this reason, PEAR came into being and was distributed along with the PHP core starting from 4.04.

What benefits can PEAR bring to me?
1. As mentioned earlier, PEAR manages PEAR application code bases according to certain categories. Your PEAR code can be organized into appropriate directories, and others can easily retrieve and share your results.

It is not just a code repository, it is also a standard. Using this standard to write your PHP code will enhance the readability, reusability of your program, and reduce the chance of errors.

By providing 2 classes, it builds a framework for you, implements functions such as destructors and error capture, which you can use by inheriting.

PEAR coding rules
PEAR's encoding rules include indentation rules, control structures, function calls, function definitions, annotations, including code, PHP tags, comment blocks of file headers, CVS tags, URL examples, and constant naming. Here is a brief introduction:

Indentation rules:
4 spaces are required to indent the code in PEAR and do not use TAB. If you use VIM, put the following settings into your ~/.vimrc:
set expandtab
set shiftwidth=4
set tabstop=4


If you use Emacs/XEmacs, you need to set indent-tabs-mode to nil.

However, like me, you like to edit PHP files with (X)Emacs. I highly recommend you install PHP-MODE, so that when you write PEAR code, it will automatically adjust your indentation style. Of course, PHP-MODE has many excellent features. You can download the latest version of PHP-MODE from the resource list.

Control structure:
The control structure mentioned here includes: if for while switch, etc. For the control structure, you should empty a space after the keyword (such as if for ..), and then follow the control brackets, so that it will not be confused with function calls. In addition, you should try to use curly brackets {} as completely, even if they are syntactically optional. This can prevent you from logical doubts or errors when adding new lines of code in the future. Here is a sample:
if ((condition 1) && (condition 2)) {
Statement 1;
}else if ((condition 3)
(condition 4)) {
Statement 2;
}else {
Statement 3;
}




Function call:
For function calls, there should be no spaces between the function name and the left bracket (there should be no spaces between the function parameters. For function parameters, there should be the same space separation between the separated comma and the next parameter, and there should be no spaces between the last parameter and the closing bracket. The following is a standard function call;
$result = foo($param1, $param2, $param3);
Irregular writing:
$result=foo ($param1,$param2,$param3);
$result=foo( $param1,$param2, $param3 );




In addition, if you want to assign the return result of the function, then there must be spaces between the equal sign and the assigned variable. At the same time, if it is a series of related assignment statements, you add appropriate spaces to align them, just like this:
$result1 = $foo($param1, $param2, $param3);
$var2 = $foo($param3);
$var3 = $foo($param4, $param5);




Function definition:
Function definition follows the custom of "one true brace":
function connect(&$dsn, $persistent = false)
{
if (is_array($dsn)) {
$dsninfo = &&dsn;
} else {
$dsninfo = DB::parseDSN($dsn);
}

if (!$dsninfo
!$dsninfo['phptype']) {
return $this->raiseError();
}
return true;
}


As shown above, optional parameters are to be at the end of the parameter table and always try to return meaningful function values.

About the comments:
For online documents of classes, they should be able to be converted by PHPDoc, just like JavaDoc. PHPDoc is also a PEAR application, you can go to / to view for more detailed introduction. In addition to online documents of classes, it is recommended that you use non-documentary annotations to interpret your code. When you see a piece of code, you think: Oh, I don’t think you need to describe it carefully in the document. Then you'd better give this code a simple comment so you won't forget how they work. For comment forms, C /* */ and C++ // are both good, but don't use the # comment method of Perl or shell.

Contains code:
Whenever you need to include a class file unconditionally, you must use require_once; when you need to include a class file, you must use include_once; this ensures that the file you want to include will only be included once, and these two statements share the same file list, so you don't have to worry about confusion between the two. Once require_once contains a file, include_once will not repeatedly include the same file, and vice versa.

PHP code tags:
You should use <?php ?> to define your php code at any time, instead of simply using <? ?>, which can ensure PEAR compatibility and facilitate cross-platform migration.

Comment statement for file header:
All PHP code files that need to be included in the PEAR core release. At the beginning of the file, you must include the following comment statement:
/* vim: set expandtab tabstop=4 shiftwidth=4: */

// +----------------------------------------------------------------------+

// | PHP version 4.0 |

// +----------------------------------------------------------------------+

// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |

// +----------------------------------------------------------------------+

// | This source file is subject to version 2.0 of the PHP license, |

// | that is bundled with this package in the file LICENSE, and is |

// | available at through the world-wide-web at |

// | /license/2_02.txt. |

// | If you did not receive a copy of the PHP license and are unable to |

// | obtain it through the world-wide-web, please send a note to |

// | license@ so we can mail you a copy immediately. |

// +----------------------------------------------------------------------+

// | Authors: Original Author |

// | Your Name |

// +----------------------------------------------------------------------+

//

// $Id$


For files not in the PEAR core code base, it is recommended that you also have a similar comment block at the beginning of the file, indicating the copyright, agreement, author, etc. At the same time, VIM's MODELINE is also added to the first line, so that the PEAR code style can be maintained in VIM.

CVS tags:
As shown above, add the CVS ID tag to each file. If the file you edited or modified does not have this tag, please add it, or replace the similar manifestations in the original file (such as "Last modified" etc.)

URL sample:
You can refer to RFC 2606 and use "" as all URL samples.

Constant naming:
Constants should be capitalized as much as possible. For easy understanding, use underscores to split each word. At the same time, you should prefix the package name or class name where the constant is located. For example, constants in bug classes should start with Bug_. The above are the encoding rules of PEAR. For detailed encoding rules, please refer to the description of the CODING_STANDDARD file in PEAR. To better understand these coding rules, you can also refer to the code of the existing PEAR core module.

Get started with PEAR

PEAR
Using PEAR is simple, you just need to define your own PEAR program like this:
require_once "";
class your_class_name extends PEAR{
Your class definition...
}




Of course, you need to abide by the PEAR coding rules mentioned above, and then you can implement what you want to do inside your class. Let's discuss it in detail. In fact, PEAR provides us with 2 predefined classes:
PEAR: This is the base class of PEAR, and all PEAR extensions must be derived from it.
PEAR_Error: The base class for PEAR error handling, you can choose to derive your own error handling class.

Generally speaking, you should not create an instance of PEAR directly, but instead derive a new class yourself and then create an instance of this new class. As a base class, PEAR provides us with some useful functions, the most important of which are destructors and error handling

Destructor
PHP supports constructors, but does not support destructors. However, PHP provides the function register_shutdown_function(), so that the registered function can be called back before the script terminates. Therefore, PEAR uses this feature to provide simulation of the destructor. If you have a subclass of PEAR, called mypear, then in the mypear class, you can define a function, the function name is underscore plus your class name, _mypear(), this function is the destructor of this class. However, this destructor is different from the destructor in C++. It will not be executed when the object is deleted, but when the script ends. After all, this is just a simulation. Since register_shutdown_function() is used, the printed information will not be returned to the browser in your destructor. In addition, in your constructor, you need to call the constructor of its parent class, because PHP will not automatically call the constructor of the parent class, and the destructor needs to be registered in the constructor of PEAR. We can take a look at the source code of PEAR:
<code>
function PEAR() {
if (method_exists($this, "_".get_class($this))) {
global $_PEAR_destructor_object_list;
$_PEAR_destructor_object_list[] = &&this;
}
if ($this->_debug) {
printf("PEAR constructor called, class=%s\n",
get_class($this));
}
.....
function _PEAR_call_destructors() {
global $_PEAR_destructor_object_list;
if (is_array($_PEAR_destructor_object_list) && sizeof($_PEAR_destructor_object_list)) {
reset($_PEAR_destructor_object_list);
while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
$destructor = "_".get_class($objref);
if (method_exists($objref, $destructor)) {
$objref->$destructor();
}
}
//Clear the registered object list,

//Prevent repeated calls

$_PEAR_destructor_object_list = array();

}

}

....
register_shutdown_function("_PEAR_call_destructors");
</code>




The above code shows how PEAR implements a destructor. In the component function, it will check whether there is a destructor in the current class. If there is, the reference to the current class will be placed in a global list. In _PEAR_call_destructors, it will check whether there is a corresponding destructor in each element in this global list. If there is, it will be called and the global list will be cleared.

In the last line of code, register_shutdown_function("_PEAR_call_destructors") is called to register_PEAR_call_destructors, so that when the script is executed, PHP will call back this function. Using the destructor, you can do some necessary "aftermath" work before processing the user's request and exiting. Typical examples are that you can close open files, disconnect the database, store some data to disk, etc.

Error handling
PEAR allows you to handle errors in many ways. You not only simply return an error code or error information, but can return a PEAR_Error object, or a new error object derived from PEAR_Error.

The error object in PEAR does not have a specific output form. It can just catch errors and not return too much information to the user. It can also call back a special error handling function. At the same time, even if the error information is output, it forces you to be in HTML form. You can output XML, CSV form, or other forms you define yourself. You only need to derive a new class from PEAR_Error, and then create and "throw" the object of this new class at the appropriate time.

Simple error handling:
In PEAR, the simplest error handling is to "throw" this error, you just need to simply create and return a PEAR_Error object. Here is a simple example:
<code>
function myconnect($host = "localhost", $port = 1080)
{
$fp = fsockopen($host, $port, $errno, $errstr);
if (!is_resource($fp)) {
return new PEAR_Error($errstr, $errno);
}
return $fp;
}

$sock = myconnect();
if (PEAR::isError($sock)) {
print "connect error: ".$sock->getMessage()."<BR>\n"
}
</code>


As shown in the above code, after executing a piece of code that may cause an error, you need to use PEAR's isError to detect whether there is an error, and you can use PEAR_Error's getMessage to get the latest error message. Note: Be sure to use PEAR::isError in critical places

Use raiseError

After PHP4.0.5, PEAR has two additional functions:
setErrorHandling($mode, $options = null)
raiseError($message = null, $code = null, $mode = null,$options = null, $userinfo = null)


The former can set the default error handling mode of PEAR, and the latter is a wrapper function that returns a PEAR_Error object. The slightly different from the object that directly creates and returns PEAR_Error, if the parameters such as $mode, $options are omitted, it will use the default value to create this PEAR_Error object. You can use setErrorHandling() to customize these default values.

PEAR_Error
PEAR_Error is a base class of PEAR's error object. Unlike PEAR, generally speaking, you can directly create an instance of PEAR_Error, which is created as follows:
$error = new PEAR_Error($message, $code, $mode, $options, $userinfo);

$message is your error message, $code is the error number of the error, and the last 3 parameters are closely related:
$mode: is the processing mode for this error, and the following constants can be used:
PEAR_ERROR_RETURN: Only return this error object (default method)
PEAR_ERROR_PRINT: Print this error message in the build function, but the current program will continue to run.
PEAR_ERROR_TRIGGER: Use PHP's trigger_error() to trigger an error. If you have set the error handling function, or you set the PHP's error handling level to E_USER_ERROR, the current program will be terminated.
PEAR_ERROR_DIE: Print error and exit, program terminates.
PEAR_ERROR_CALLBACK: Use a callback function or method to handle the current error and the program terminates.
$options: This parameter only works when $mode is PEAR_ERROR_TRIGGER and PEAR_ERROR_CALLBACK. If it is PEAR_ERROR_TRIGGER, $options must be one of three constants: E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR, which is the same as the value of trigger_error in PHP. If $mode is PEAR_ERROR_CALLBACK, $options can be a string, the content is the function name to be called, or it can be an array of 2 elements, an object variable, and a string (specifying the method to be called).
$userinfo: Stores additional user information, you can place the relevant debugging information here.

There are some commonly used methods in PEAR_Error. These methods are not described in the PHP document, and are listed here:

int getMode: Returns the current error handling mode, integer.
string getMessage: Returns the current complete error message, string.
mixed getCallback: Returns the current callback information, which may be the function name of the callback, or an array of (object, method).
int getCode: Returns the error code of the integer.
string getType: Returns the wrong type, that is, the current class name, string.
string getUserInfo: Returns the additional user information, string.
string getDebugInfo: The content is the same as above.
string toString: Returns the detailed string description of the current object, including the error handling pattern, level, error information, error code, related callback functions, etc.

Summarize
At this point, the introduction to PEAR is over. To sum up, if you want to create a PEAR extension application, you need to do this:

require_once ""
Use class your_pear_extend extends PEAR{} to define your new class.
In your class constructor, call the constructor of the parent class PEAR:
function your_pear_extend{

$this->PEAR();

...
}



If needed, define your destructor _your_pear_extend
If necessary, derive your own error handling class from PEAR_Error
Set your error handling mode and trigger the error when appropriate.
After executing code that may produce an error, use PEAR::isError($obj) to catch the corresponding error.
Implement your own functions.
In the latest PEAR core release of PHP4.05, there are already many excellent application modules, such as: PHPDoc, Cache, HTML... Of course, compared with CPAN, PEAR is just starting out, and it requires the joint efforts of the people in the PHP community to improve it and enhance it, so that PHP will become more and more powerful.