<?xml version="1.0" encoding="iso-8859-1"?>
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns="http://purl.org/rss/1.0/"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
>
    <channel rdf:about="http://pear.php.net">
    <link>http://pear.php.net/</link>
    <dc:creator>pear-webmaster@lists.php.net</dc:creator>
    <dc:publisher>pear-webmaster@lists.php.net</dc:publisher>
    <dc:language>en-us</dc:language><items>
<rdf:Seq><rdf:li rdf:resource="http://pear.php.net/pepr/pepr-proposal-show.php?id=617"/>
<rdf:li rdf:resource="http://pear.php.net/pepr/pepr-proposal-show.php?id=616"/>
<rdf:li rdf:resource="http://pear.php.net/pepr/pepr-proposal-show.php?id=611"/>
<rdf:li rdf:resource="http://pear.php.net/pepr/pepr-proposal-show.php?id=609"/>
<rdf:li rdf:resource="http://pear.php.net/pepr/pepr-proposal-show.php?id=606"/>
<rdf:li rdf:resource="http://pear.php.net/pepr/pepr-proposal-show.php?id=605"/>
<rdf:li rdf:resource="http://pear.php.net/pepr/pepr-proposal-show.php?id=603"/>
<rdf:li rdf:resource="http://pear.php.net/pepr/pepr-proposal-show.php?id=593"/>
<rdf:li rdf:resource="http://pear.php.net/pepr/pepr-proposal-show.php?id=591"/>
<rdf:li rdf:resource="http://pear.php.net/pepr/pepr-proposal-show.php?id=585"/>
</rdf:Seq>
</items>

<title>PEPr: Latest proposals with status Proposed</title>
<description>The latest PEPr proposals with status Proposed</description>
</channel>

<item rdf:about="http://pear.php.net/pepr/pepr-proposal-show.php?id=617">
 <title>PEPr Proposal [617]: Internationalization::Arabic</title>
 <link>http://pear.php.net/pepr/pepr-proposal-show.php?id=617</link>
 <content:encoded>&lt;br /&gt;
Proposed package:        Internationalization::Arabic&lt;br /&gt;&lt;br /&gt;
Proposer:                &lt;a href=&quot;/user/arphp&quot;&gt;Khaled Al-Shamaa&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;
Class enhances developing Arabic web applications by providing set of methods to process and present Arabic text such as:&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
* Arabic text auto summarization (&lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/ArAutoSummarize.php&quot;&gt;Example&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;
* Advanced Arabic search (&lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/ArQuery.php&quot;&gt;Example&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;
* Render Arabic text (PDF, GD, SWF, VRML, etc...) (&lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/ArGlyphs_GD.php&quot;&gt;Example&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;
* Present dates in Arabic or Hijri (&lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/ArDate.php&quot;&gt;Example&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;
* Convert Hijri date into Unix timestamp (&lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/ArMktime.php&quot;&gt;Example&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;
* Parse Arabic textual datetime into timestamp (&lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/ArStrToTime.php&quot;&gt;Example&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;
* Transliterate English words in Arabic and vice versa (&lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/ArTransliteration.php&quot;&gt;Example&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;
* Spell numbers in Arabic idiom (&lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/ArNumbers.php&quot;&gt;Example&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;
* Phonetically alike Arabic words (&lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/ArSoundex.php&quot;&gt;Example&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;
* Identify Arabic in multi language UTF-8 documents (&lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/ArIdentifier.php&quot;&gt;Example&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;
* Identify names &amp;amp; places in Arabic text (&lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/ArWordTag.php&quot;&gt;Example&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;
* Guess gender of Arabic names (&lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/ArGender.php&quot;&gt;Example&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;
* Convert keyboard language programmatically (&lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/ArKeySwap.php&quot;&gt;Example&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;
* Calculate time of Muslim prayer and Qibla direction (&lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/Salat.php&quot;&gt;Example&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;
* Standardize Arabic text (&lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/ArStandard.php&quot;&gt;Example&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
and &lt;a href=&quot;http://www.ar-php.org/I18N_Arabic/I18N_Arabic/Examples/&quot;&gt;more&lt;/a&gt; ...&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
For more information please visit &lt;a href=&quot;http://ar-php.org/en_index_php_arabic.html&quot;&gt;PHP and Arabic Language&lt;/a&gt; project website
 </content:encoded>
 <dc:date>2009-11-02T07:21:15-05:00</dc:date>
</item>
<item rdf:about="http://pear.php.net/pepr/pepr-proposal-show.php?id=616">
 <title>PEPr Proposal [616]: XML::Create_KML</title>
 <link>http://pear.php.net/pepr/pepr-proposal-show.php?id=616</link>
 <content:encoded>&lt;br /&gt;
Proposed package:        XML::Create_KML&lt;br /&gt;&lt;br /&gt;
Proposer:                &lt;a href=&quot;/user/hamstar&quot;&gt;Robert McLeod&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;
Class for creating KML code from a data source and outputing it to either a file or string
 </content:encoded>
 <dc:date>2009-09-30T12:53:38-05:00</dc:date>
</item>
<item rdf:about="http://pear.php.net/pepr/pepr-proposal-show.php?id=611">
 <title>PEPr Proposal [611]: Images::Image_Diff</title>
 <link>http://pear.php.net/pepr/pepr-proposal-show.php?id=611</link>
 <content:encoded>&lt;br /&gt;
Proposed package:        Images::Image_Diff&lt;br /&gt;&lt;br /&gt;
Proposer:                &lt;a href=&quot;/user/skwashd&quot;&gt;Dave Hall&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;
Compare the differences between 2 images&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Checks any image format supported by GD.
 </content:encoded>
 <dc:date>2009-09-03T03:06:46-05:00</dc:date>
</item>
<item rdf:about="http://pear.php.net/pepr/pepr-proposal-show.php?id=609">
 <title>PEPr Proposal [609]: Database::Database_SQL_Intervals</title>
 <link>http://pear.php.net/pepr/pepr-proposal-show.php?id=609</link>
 <content:encoded>&lt;br /&gt;
Proposed package:        Database::Database_SQL_Intervals&lt;br /&gt;&lt;br /&gt;
Proposer:                &lt;a href=&quot;/user/rozesamuel&quot;&gt;Samuel ROZE&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Database_SQL_Intervals&lt;/strong&gt; does an abstraction between an SQL table which is formated as a hierarchy table using intervals. It help developper to use a hierarchy without many reflexions. The class is able to:&lt;br /&gt;&lt;br /&gt;
- Create elements [into others]&lt;br /&gt;&lt;br /&gt;
- Remove elements (and its children)&lt;br /&gt;&lt;br /&gt;
- Move element into another&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;A new hierarchy gestion&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;
Hierarchy gestion is a complex think and in a database or in a static file, this hierachy have to be structured to be (re)used after. The hierarchy gestion using intervals is a way to structure your hierarchy tables. Contrary to recursive method, the intervals method provide a very simple DB structure which can be (partitaly or not) export even more simply !&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;A more complex table&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;
In fact, (just!) into the table, values structure is more complex. It's why using a library to manage these tables is great : you're sure that you'll not break the table integrity with your table management.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Very simple to use:&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;
$sql = PDO( ... );&lt;br /&gt;&lt;br /&gt;
$intervalles = new Database_SQL_Intervals($sql);&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
$intervalles-&amp;gt;add('my_table', $parent, array('field' =&amp;gt; 'value'));&lt;br /&gt;&lt;br /&gt;
$intervalles-&amp;gt;move('my_table', $object, $target);&lt;br /&gt;&lt;br /&gt;
$intervalles-&amp;gt;remove('my_table', $object);&lt;br /&gt;&lt;br /&gt;
?&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Example&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;
Consider a table &amp;quot;my_table&amp;quot; like this:&lt;br /&gt;&lt;br /&gt;
&lt;img src=&quot;http://projects.d-sites.com/librairies/Database_SQL_Intervals/images/ex1.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;&amp;lt;?php &lt;br /&gt;&lt;br /&gt;
require_once 'Database/SQL_Intervals.php'; &lt;br /&gt;&lt;br /&gt;
require_once 'Database/SQL_Intervals_mysql.php'; &lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
define('TABLE', 'my_table'); &lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
// Creation of the database access&lt;br /&gt;&lt;br /&gt;
$sql = new PDO('mysql:host=localhost;dbname=tests', 'root', ''); &lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
// Creation of the Database_SQL_Intervals instance&lt;br /&gt;&lt;br /&gt;
$intervals = new Database_SQL_Intervals($sql); &lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
// Creation of elements...&lt;br /&gt;&lt;br /&gt;
$first = $intervals-&amp;gt;add(TABLE, 1, array('other1' =&amp;gt; 'first'));&lt;br /&gt;&lt;br /&gt;
$second = $intervals-&amp;gt;add(TABLE, 1, array('other1' =&amp;gt; 'first2', 'other2' =&amp;gt; 'value2'));&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
// ... and children&lt;br /&gt;&lt;br /&gt;
$intervals-&amp;gt;add(TABLE, $second, array('other1' =&amp;gt; 'child');&lt;br /&gt;&lt;br /&gt;
$last = $intervals-&amp;gt;add(TABLE, $second, array('other2' =&amp;gt; 'child');&lt;br /&gt;&lt;br /&gt;
?&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
At the moment, we have a table like:&lt;br /&gt;&lt;br /&gt;
&lt;img src=&quot;http://projects.d-sites.com/librairies/Database_SQL_Intervals/images/ex2.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Which is provide this hierarchy:&lt;br /&gt;&lt;br /&gt;
&lt;img src=&quot;http://projects.d-sites.com/librairies/Database_SQL_Intervals/images/ex2-2.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;
// Move&lt;br /&gt;&lt;br /&gt;
$intervals-&amp;gt;move(TABLE, $second, $first);&lt;br /&gt;&lt;br /&gt;
$intervals-&amp;gt;move(TABLE, $last, 1); // 1 = Top-Father&lt;br /&gt;&lt;br /&gt;
?&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
At the end of the first function, we have a hierarchy tree like:&lt;br /&gt;&lt;br /&gt;
&lt;img src=&quot;http://projects.d-sites.com/librairies/Database_SQL_Intervals/images/ex3.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
And at the end of the second function:&lt;br /&gt;&lt;br /&gt;
&lt;img src=&quot;http://projects.d-sites.com/librairies/Database_SQL_Intervals/images/ex4.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Which it structured into the table:&lt;br /&gt;&lt;br /&gt;
&lt;img src=&quot;http://projects.d-sites.com/librairies/Database_SQL_Intervals/images/ex5.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
To remove an object, you just have to call &amp;quot;remove&amp;quot; method:&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;
$intervals-&amp;gt;remove(TABLE, $second);&lt;br /&gt;&lt;br /&gt;
?&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
And the tree's like that:&lt;br /&gt;&lt;br /&gt;
&lt;img src=&quot;http://projects.d-sites.com/librairies/Database_SQL_Intervals/images/ex6.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Note:&lt;/strong&gt; package.xml &amp;amp; documentations will be generated after corrections which you'll give me will be done. :)&lt;br /&gt;&lt;br /&gt;
See test/tests.php
 </content:encoded>
 <dc:date>2009-08-19T21:40:44-05:00</dc:date>
</item>
<item rdf:about="http://pear.php.net/pepr/pepr-proposal-show.php?id=606">
 <title>PEPr Proposal [606]: RFC::Drop requirement of renaming a package when migrating from PHP 4.x to PHP 5.x</title>
 <link>http://pear.php.net/pepr/pepr-proposal-show.php?id=606</link>
 <content:encoded>&lt;br /&gt;
Proposed package:        RFC::Drop requirement of renaming a package when migrating from PHP 4.x to PHP 5.x&lt;br /&gt;&lt;br /&gt;
Proposer:                &lt;a href=&quot;/user/nohn&quot;&gt;Sebastian Nohn&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;
This RFC proposes to drop the requirement of renaming a package when migrating from PHP 4.x to PHP 5.x. It should be a cleare exception for migration from 4.x to 5.x, not within 4.x nor within 5.x nor from 5.x to 6.x.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
It would however also be possible to have a fixed rule like &amp;quot;1.5 years after the end of life of a PHP version it is allowed to bump PHP version requirements to any release in the next major version without having to rename the Package&amp;quot;.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
All that needs to be said is on &lt;a href=&quot;http://gophp5.org/&quot;&gt;http://gophp5.org/&lt;/a&gt;. People may still argue for PHP 4 like &amp;quot;it always has worked&amp;quot; or &amp;quot;I don't want to upgrade because...&amp;quot; but see the facts: PHP 4 is dead. It's not supported anymore by PHP.net, receives no bug fixes, no security fixes no attention at all.
 </content:encoded>
 <dc:date>2009-07-16T20:25:30-05:00</dc:date>
</item>
<item rdf:about="http://pear.php.net/pepr/pepr-proposal-show.php?id=605">
 <title>PEPr Proposal [605]: Mail::Mail_CheckUser</title>
 <link>http://pear.php.net/pepr/pepr-proposal-show.php?id=605</link>
 <content:encoded>&lt;br /&gt;
Proposed package:        Mail::Mail_CheckUser&lt;br /&gt;&lt;br /&gt;
Proposer:                &lt;a href=&quot;/user/miyauchi&quot;&gt;Takayuki Miyauchi&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;
The Mail_CheckUser is check email addresses for validity with SMTP commands.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
qmail,other non-monolithic mail servers and Some spam mail filters often report that a user exists even if it is not so.&lt;br /&gt;&lt;br /&gt;
But network checks of this package is useful for the decrease of the bounced email by the misspelling, server errors etc.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
You should add SPF record to your domain's DNS configuration.&lt;br /&gt;&lt;br /&gt;
If you don't, response of 5xx might be returned also to the existing address.&lt;br /&gt;&lt;br /&gt;
 (e.g hotmail and other)&lt;br /&gt;&lt;br /&gt;
In that case, Your server can't send email to those servers.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
1) This will check email address by regex with The Mail_RFC822 package&lt;br /&gt;&lt;br /&gt;
2) Next, This will send SMTP commands with The Net_SMTP package&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
HELO fqdn  # constructor param&lt;br /&gt;&lt;br /&gt;
Mail From: sender@example.com # constructor param&lt;br /&gt;&lt;br /&gt;
RCPT TO: check@example.net&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
3) Check response code from SMTP server and return true or flase.&lt;br /&gt;&lt;br /&gt;
    Default, if response code is 250 or 251, return true.&lt;br /&gt;&lt;br /&gt;
    Response code for true can customize.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
example:&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;$chk = new CheckUser($fqdn, $sender);&lt;br /&gt;&lt;br /&gt;
if ( $chk-&amp;gt;checkUser($_POST['email']) ) {&lt;br /&gt;&lt;br /&gt;
    print &amp;quot;OK&amp;quot;;&lt;br /&gt;&lt;br /&gt;
}else{&lt;br /&gt;&lt;br /&gt;
    print &amp;quot;Invalid email address&amp;quot;;&lt;br /&gt;&lt;br /&gt;
}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
If you think almost every other situation indicates 'possible' success.&lt;br /&gt;&lt;br /&gt;
You can set response code to return true.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
example:&lt;br /&gt;&lt;br /&gt;
It will return true when SMTP SEVER connection failed and other temporary error.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;$chk = new CheckUser($fqdn, $sender);&lt;br /&gt;&lt;br /&gt;
$chk-&amp;gt;setOKCodes(1001,450,451,452);&lt;br /&gt;&lt;br /&gt;
if ( $chk-&amp;gt;checkUser($_POST['email']) ) {&lt;br /&gt;&lt;br /&gt;
    print &amp;quot;OK&amp;quot;;&lt;br /&gt;&lt;br /&gt;
}else{&lt;br /&gt;&lt;br /&gt;
    print &amp;quot;Invalid email address&amp;quot;;&lt;br /&gt;&lt;br /&gt;
}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
getResponse() method will returun SMTP response information as array.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
e.g.&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;array(2) {&lt;br /&gt;&lt;br /&gt;
  [0]=&amp;gt;&lt;br /&gt;&lt;br /&gt;
  int(550)&lt;br /&gt;&lt;br /&gt;
  [1]=&amp;gt;&lt;br /&gt;&lt;br /&gt;
  string(100) &amp;quot;5.1.1 &amp;lt;unknown@example.com&amp;gt;: Recipient address rejected: User unknown in local recipient table&amp;quot;&lt;br /&gt;&lt;br /&gt;
}&lt;/code&gt;
 </content:encoded>
 <dc:date>2009-07-15T09:35:10-05:00</dc:date>
</item>
<item rdf:about="http://pear.php.net/pepr/pepr-proposal-show.php?id=603">
 <title>PEPr Proposal [603]: Authentication::OpenID</title>
 <link>http://pear.php.net/pepr/pepr-proposal-show.php?id=603</link>
 <content:encoded>&lt;br /&gt;
Proposed package:        Authentication::OpenID&lt;br /&gt;&lt;br /&gt;
Proposer:                &lt;a href=&quot;/user/shupp&quot;&gt;Bill Shupp&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;
&lt;p&gt;OpenID is a PHP implementation of the OpenID 1.1 and 2.0 specifications.  OpenID is a free and easy way to use a single digital identity across the Internet. See &lt;a href=&quot;http://openid.net&quot; onclick=&quot;window.open(this.href, '_blank'); return false;&quot;&gt;openid.net&lt;/a&gt;  for details.&lt;/p&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;Only Relying Party support is complete at this time.  Provider support is already underway, I just didn't want to hold up the proposal in the meantime, as I'll be using the RP support initially for work.&lt;/p&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;There is out of the box support for a few extensions, including Simple Registration (1.0 and 1.1), Attribute Exchange, and some support for the new UI extension.&lt;/p&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;This package supports a storage interface (including &lt;a href=&quot;http://pear.php.net/cache_lite&quot; onclick=&quot;window.open(this.href, '_blank'); return false;&quot;&gt;Cache_Lite&lt;/a&gt; and &lt;a href=&quot;http://pear.php.net/mdb2&quot; onclick=&quot;window.open(this.href, '_blank'); return false;&quot;&gt;MDB2&lt;/a&gt; drivers) for easy addition of custom drivers.  There is also support for observers for logging, etc.&lt;/p&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;There is an example web console for testing discovery, relying party (with some useful debugging functionality), and also a sample implementation of an &lt;a href=&quot;http://code.google.com/p/openid-selector/&quot; onclick=&quot;window.open(this.href, '_blank'); return false;&quot;&gt;OpenID JS Selector&lt;/a&gt; (i.e. the &amp;quot;NASCAR&amp;quot; solution).&lt;/p&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;You can try the examples here: &lt;sup&gt;&lt;a href=&quot;http://shupp.org/openid/examples&quot; onclick=&quot;window.open(this.href, '_blank'); return false;&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;A few notes about this package:&lt;/p&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
    &lt;li&gt;There is about 88% code coverage in unit tests.  The rest (in storage and discovery) will be completed soon.&lt;/li&gt;&lt;br /&gt;
    &lt;li&gt;HTTP_Request is used instead of HTTP_Request2 because following redirects was not included in HTTP_Request2.  This package may move over to HTTP_Client instead, but that it not yet decided.&lt;/li&gt;&lt;br /&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;br /&gt;

 </content:encoded>
 <dc:date>2009-07-06T16:49:52-05:00</dc:date>
</item>
<item rdf:about="http://pear.php.net/pepr/pepr-proposal-show.php?id=593">
 <title>PEPr Proposal [593]: Web Services::Services_WhitePages</title>
 <link>http://pear.php.net/pepr/pepr-proposal-show.php?id=593</link>
 <content:encoded>&lt;br /&gt;
Proposed package:        Web Services::Services_WhitePages&lt;br /&gt;&lt;br /&gt;
Proposer:                &lt;a href=&quot;/user/johntse&quot;&gt;Juan Manuel Fernandez Arauz&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;
This package works the WhitePages 1.0 API (&lt;a href=&quot;http://www.whitepages.com/&quot;&gt;www.whitepages.com&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;
It can retrieve information about a person, a business, a thelephone number and an address.&lt;br /&gt;&lt;br /&gt;
Also there are functions for counting the results and get information of all or one specific register.
 </content:encoded>
 <dc:date>2009-03-16T20:22:29-05:00</dc:date>
</item>
<item rdf:about="http://pear.php.net/pepr/pepr-proposal-show.php?id=591">
 <title>PEPr Proposal [591]: Encryption::Crypt_FSHP</title>
 <link>http://pear.php.net/pepr/pepr-proposal-show.php?id=591</link>
 <content:encoded>&lt;br /&gt;
Proposed package:        Encryption::Crypt_FSHP&lt;br /&gt;&lt;br /&gt;
Proposer:                &lt;a href=&quot;/user/bdd&quot;&gt;Berk D. Demir&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;
/**&lt;br /&gt;&lt;br /&gt;
 * Fairly Secure Hashed Passwords. A PBKDF1 similar implementation.&lt;br /&gt;&lt;br /&gt;
 *&lt;br /&gt;&lt;br /&gt;
 * Fairly Secure Hashed Password (FSHP) is a salted, iteratively hashed&lt;br /&gt;&lt;br /&gt;
 * password hashing implementation.&lt;br /&gt;&lt;br /&gt;
 *&lt;br /&gt;&lt;br /&gt;
 * Design principle is similar with PBKDF1 specification in RFC 2898 &lt;br /&gt;&lt;br /&gt;
 * (a.k.a: PKCS #5: Password-Based Cryptography Specification Version 2.0)&lt;br /&gt;&lt;br /&gt;
 *&lt;br /&gt;&lt;br /&gt;
 * FSHP allows choosing the salt length, number of iterations and the&lt;br /&gt;&lt;br /&gt;
 * underlying cryptographic hash function among SHA-1 and SHA-2 (256, 384, 512).&lt;br /&gt;&lt;br /&gt;
 *&lt;br /&gt;&lt;br /&gt;
 * SECURITY:&lt;br /&gt;&lt;br /&gt;
 * Default FSHP1 uses 8 byte salts, with 4096 iterations of SHA-256 hashing.&lt;br /&gt;&lt;br /&gt;
 *  - 8 byte salt renders rainbow table attacks impractical by multiplying the&lt;br /&gt;&lt;br /&gt;
 *    required space with 2^64.&lt;br /&gt;&lt;br /&gt;
 *  - 4096 iterations causes brute force attacks to be fairly expensive.&lt;br /&gt;&lt;br /&gt;
 *  - There are no known attacks against SHA-256 to find collisions with&lt;br /&gt;&lt;br /&gt;
 *    a computational effort of fewer than 2^128 operations at the time of&lt;br /&gt;&lt;br /&gt;
 *    this release.&lt;br /&gt;&lt;br /&gt;
 *&lt;br /&gt;&lt;br /&gt;
 * BASIC OPERATION:&lt;br /&gt;&lt;br /&gt;
 * &amp;lt;code&amp;gt;&lt;br /&gt;&lt;br /&gt;
 * $fsh = Crypt_FSHP::crypt('OrpheanBeholderScryDoubt');&lt;br /&gt;&lt;br /&gt;
 * &amp;lt;/code&amp;gt;&lt;br /&gt;&lt;br /&gt;
 * &amp;lt;samp&amp;gt;&lt;br /&gt;&lt;br /&gt;
 * Return Value:&lt;br /&gt;&lt;br /&gt;
 * {FSHP1|8|4096}GVSUFDAjdh0vBosn1GUhzGLHP7BmkbCZVH/3TQqGIjADXpc+6NCg3g==&lt;br /&gt;&lt;br /&gt;
 * &amp;lt;/samp&amp;gt;&lt;br /&gt;&lt;br /&gt;
 * &amp;lt;code&amp;gt;&lt;br /&gt;&lt;br /&gt;
 * Crypt_FSHP::check('OrpheanBeholderScryDoubt', $fsh);&lt;br /&gt;&lt;br /&gt;
 * &amp;lt;/code&amp;gt;&lt;br /&gt;&lt;br /&gt;
 * &amp;lt;samp&amp;gt;&lt;br /&gt;&lt;br /&gt;
 * Return Value:&lt;br /&gt;&lt;br /&gt;
 * true&lt;br /&gt;&lt;br /&gt;
 * &amp;lt;/samp&amp;gt;&lt;br /&gt;&lt;br /&gt;
 *&lt;br /&gt;&lt;br /&gt;
 * CUSTOMIZING THE CRYPT:&lt;br /&gt;&lt;br /&gt;
 * Let's set a higher password storage security baseline.&lt;br /&gt;&lt;br /&gt;
 *  - Increase the salt length from default 8 to 16.&lt;br /&gt;&lt;br /&gt;
 *  - Increase the hash rounds from default 4096 to 8192.&lt;br /&gt;&lt;br /&gt;
 *  - Select FSHP3 with SHA-512 as the underlying hash algorithm.&lt;br /&gt;&lt;br /&gt;
 *&lt;br /&gt;&lt;br /&gt;
 * &amp;lt;code&amp;gt;&lt;br /&gt;&lt;br /&gt;
 * Crypt_FSHP::crypt('ExecuteOrder66', null, 16, 8192, 3);&lt;br /&gt;&lt;br /&gt;
 * &amp;lt;/code&amp;gt;&lt;br /&gt;&lt;br /&gt;
 * &amp;lt;samp&amp;gt;&lt;br /&gt;&lt;br /&gt;
 * Return Value:&lt;br /&gt;&lt;br /&gt;
 * {FSHP3|16|8192}0aY7rZQ+/PR+Rd5/I9ssRM7cjguyT8ibypNaSp/.....wyJJa2EqOsq4Io=&lt;br /&gt;&lt;br /&gt;
 * &amp;lt;/samp&amp;gt;&lt;br /&gt;&lt;br /&gt;
 *&lt;br /&gt;&lt;br /&gt;
 * PHP version 5&lt;br /&gt;&lt;br /&gt;
 *&lt;br /&gt;&lt;br /&gt;
 * @category Encryption&lt;br /&gt;&lt;br /&gt;
 * @package  Crypt_FSHP&lt;br /&gt;&lt;br /&gt;
 * @author   Berk D. Demir &amp;lt;bdd@mindcast.org&amp;gt;&lt;br /&gt;&lt;br /&gt;
 * @license  &lt;a href=&quot;http://creativecommons.org/licenses/publicdomain/&quot;&gt;http://creativecommons.org/licenses/publicdomain/&lt;/a&gt; Public Domain&lt;br /&gt;&lt;br /&gt;
 *           Author(s) of this computer software disclaim their respective&lt;br /&gt;&lt;br /&gt;
 *           copyright on the source code and related documentation, thus&lt;br /&gt;&lt;br /&gt;
 *           releasing their work to Public Domain.&lt;br /&gt;&lt;br /&gt;
 *           In case you are forced by your lawyer to get a copyright license,&lt;br /&gt;&lt;br /&gt;
 *           you may contact any of the authors to get this software&lt;br /&gt;&lt;br /&gt;
 *           (and its related documentation) with a BSD type license.&lt;br /&gt;&lt;br /&gt;
 * @version  Release: @release_version@&lt;br /&gt;&lt;br /&gt;
 * @link     &lt;a href=&quot;http://github.com/bdd/fshp/&quot;&gt;http://github.com/bdd/fshp/&lt;/a&gt; Git Repository&lt;br /&gt;&lt;br /&gt;
 * @link     &lt;a href=&quot;http://pear.php.net/package/Crypt_FSHP/&quot;&gt;http://pear.php.net/package/Crypt_FSHP/&lt;/a&gt; PEAR&lt;br /&gt;&lt;br /&gt;
 * @since    File available since Release 0.2.2&lt;br /&gt;&lt;br /&gt;
 */
 </content:encoded>
 <dc:date>2009-02-24T00:55:16-05:00</dc:date>
</item>
<item rdf:about="http://pear.php.net/pepr/pepr-proposal-show.php?id=585">
 <title>PEPr Proposal [585]: RFC::Unit tests, new packages, good practice</title>
 <link>http://pear.php.net/pepr/pepr-proposal-show.php?id=585</link>
 <content:encoded>&lt;br /&gt;
Proposed package:        RFC::Unit tests, new packages, good practice&lt;br /&gt;&lt;br /&gt;
Proposer:                &lt;a href=&quot;/user/doconnor&quot;&gt;Daniel O'Connor&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;
The following dot points have been pretty much shamelessly taken from  &lt;a href=&quot;http://misko.hevery.com/code-reviewers-guide/&quot;&gt;http://misko.hevery.com/code-reviewers-guide/&lt;/a&gt; and other related talks, writings, etc.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
I would like to propose for all &lt;strong&gt;new&lt;/strong&gt; packages / PEPr proposals:&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;1)&lt;/strong&gt; All new packages have unit tests (PHPUnit or phpt)&lt;br /&gt;&lt;br /&gt;
If you don't have some kind of tests in your PEPr proposal, it shouldn't go to call for votes / votes should be conditional.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
They don't have to be complete, but at least a start.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
For packages before being considered a &lt;strong&gt;stable&lt;/strong&gt; release:&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;2)&lt;/strong&gt; The unit tests should completely control the test environment&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Mock out HTTP requests, database results, etc. This means really fast tests, and stops false positives.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;3)&lt;/strong&gt; Tests should cover both expected and common error cases&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
For example, if you are doing something over HTTP; inject a mock 404, 403 or 505 response; and expect certain exceptions to be raised.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;4)&lt;/strong&gt; Code should avoid the use of static methods which can't be mocked out.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;br /&gt;
// Bad:&lt;br /&gt;&lt;br /&gt;
function foo() {&lt;br /&gt;&lt;br /&gt;
    $result = Bar::someComplexSlowOperation(); // I can't make a MockBar with canned results&lt;br /&gt;&lt;br /&gt;
    return $result + 1;&lt;br /&gt;&lt;br /&gt;
}&lt;br /&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;5)&lt;/strong&gt; Use of Agile Documentation for PHPUnit tests should be encouraged - FooTest::testShouldPerformSomeAction() instead of FooTest::testMethodName()&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Hint: try phpunit --testdox YourTest some time :)&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;6)&lt;/strong&gt; An AllTests.php should be provided, so that it can integrate into pear-wide test coverage.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
See &lt;a href=&quot;http://cvs.php.net/viewvc.cgi/pear/AllTests.php?view=markup&quot;&gt;http://cvs.php.net/viewvc.cgi/pear/AllTests.php?view=markup&lt;/a&gt; and &lt;a href=&quot;http://lauken.com/doconnor/&quot;&gt;http://lauken.com/doconnor/&lt;/a&gt; for a little bit more info.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;7)&lt;/strong&gt; Aim for near 100% coverage (as much coverage as is reasonably possible, at least coverage of every method)&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;8)&lt;/strong&gt; All tests should run just fine from CVS/SVN.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
A directory structure of:&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Services_FooBar_BarFoo/Services/FooBar/BarFoo.php&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
instead of:&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Services_FooBar_BarFoo/FooBar/BarFoo.php&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Basically, when you&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;br /&gt;
cd Services_FooBar_BarFoo&lt;br /&gt;&lt;br /&gt;
phpunit tests/AllTests.php &lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
or &lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
pear run-tests -r tests/&lt;br /&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
All of the require_once's should pick up CVS's first, not the installed version&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;9)&lt;/strong&gt; If there is something which can't be mocked out - ie, a DB driver - and it needs configuration; the unit tests should skip, not fail.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
phpt:&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;br /&gt;
--SKIPIF--&lt;br /&gt;&lt;br /&gt;
&amp;lt;?php if (!file_exists('config-local.php')) { die(&amp;quot;skip Can't run test without setting up a DB server! See config-dist.php&amp;quot;); } ?&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
phpunit&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;br /&gt;
FooTest::setup() {&lt;br /&gt;&lt;br /&gt;
    if (!file_exists('config-local.php')) {&lt;br /&gt;&lt;br /&gt;
        $this-&amp;gt;markTestSkipped(&amp;quot;Can't run test without setting up a DB server! See config-dist.php&amp;quot;);&lt;br /&gt;&lt;br /&gt;
    }&lt;br /&gt;&lt;br /&gt;
}&lt;br /&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;10)&lt;/strong&gt; Unless there's a very compelling reason, your code should work just fine with PHPUnit's backupGlobals off.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
IE: Avoid using $_POST, $_GET, $_REQUEST or any other superglobals unless you are specifically designed to mess with them - HTTP_Session for instance.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;11)&lt;/strong&gt; In general, make sure you can pass dependencies in through the constructor or setters.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;br /&gt;
// Bad&lt;br /&gt;&lt;br /&gt;
function __construct() {&lt;br /&gt;&lt;br /&gt;
    $this-&amp;gt;request = new HTTP_Request2();&lt;br /&gt;&lt;br /&gt;
}&lt;br /&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;br /&gt;
// Good.&lt;br /&gt;&lt;br /&gt;
function __construct(HTTP_Request2 $request = null) {&lt;br /&gt;&lt;br /&gt;
    if ($request === null) {&lt;br /&gt;&lt;br /&gt;
       $request = new HTTP_Request2();&lt;br /&gt;&lt;br /&gt;
    }&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
    $this-&amp;gt;setRequest($request);&lt;br /&gt;&lt;br /&gt;
}&lt;br /&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;12)&lt;/strong&gt; In general, your constructor should avoid doing any Real Work - it takes values and puts them into correct places.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;br /&gt;
// Bad&lt;br /&gt;&lt;br /&gt;
function __construct(HTTP_Request2 $request) {&lt;br /&gt;&lt;br /&gt;
    $this-&amp;gt;result = $request-&amp;gt;get('http://example.com/');&lt;br /&gt;&lt;br /&gt;
}&lt;br /&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;br /&gt;
// Good&lt;br /&gt;&lt;br /&gt;
class Foo {&lt;br /&gt;&lt;br /&gt;
function __construct(HTTP_Request2 $request) {&lt;br /&gt;&lt;br /&gt;
    $this-&amp;gt;request = $request;&lt;br /&gt;&lt;br /&gt;
}&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
function fetch() {&lt;br /&gt;&lt;br /&gt;
    $this-&amp;gt;result = $this-&amp;gt;request-&amp;gt;get('http://example.com/');&lt;br /&gt;&lt;br /&gt;
}&lt;br /&gt;&lt;br /&gt;
}&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
$foo = new Foo(new HTTP_Request2());&lt;br /&gt;&lt;br /&gt;
$foo-&amp;gt;fetch();&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
or&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
function factory() {&lt;br /&gt;&lt;br /&gt;
   $foo =  new Foo(new HTTP_Request2());&lt;br /&gt;&lt;br /&gt;
   $foo-&amp;gt;fetch();&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
   return $foo;&lt;br /&gt;&lt;br /&gt;
}&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
$foo = factory();&lt;br /&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;13)&lt;/strong&gt; In general, the new operator should not appear outside of the constructor or factory methods - otherwise this cannot be mocked out.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;br /&gt;
//Bad&lt;br /&gt;&lt;br /&gt;
function bar() {&lt;br /&gt;&lt;br /&gt;
   $bar = new Bar();&lt;br /&gt;&lt;br /&gt;
   return $bar-&amp;gt;doSomething();&lt;br /&gt;&lt;br /&gt;
}&lt;br /&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;br /&gt;
//Good&lt;br /&gt;&lt;br /&gt;
function bar(Bar $bar) {&lt;br /&gt;&lt;br /&gt;
   return $bar-&amp;gt;doSomething();&lt;br /&gt;&lt;br /&gt;
}&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
function bar() {&lt;br /&gt;&lt;br /&gt;
   return $this-&amp;gt;bar-&amp;gt;doSomething();&lt;br /&gt;&lt;br /&gt;
}&lt;br /&gt;&lt;br /&gt;
&lt;/code&gt;
 </content:encoded>
 <dc:date>2008-12-29T22:46:02-05:00</dc:date>
</item>

</rdf:RDF>