You are viewing revision #5 of this wiki article.
This is the latest version of this article.
You may want to see the changes made in this revision.
I installed phpseclib because I needed to do some AES encryption in my project. After all the hassle of installing php lib, I found out that Yii already has a security module (securityManager). I finally decided to keep using phpseclib because it has one big advantage over Yii securityManager module, it does not requite mcrypt to be installed in the phpserver!
Installing phpseclib is not as straightforward as you could imagine. Yii lazy loading (I think it is called like that) is not compatible with phpseclib files because classes are not called the same as the file names they are in.
Edit: As yiqing95 pointed out, the reason the names are not the same is because of a zend and pear naming convention so the zend autoloader should be used instead of my approach of modifying the third party library. Proceed at your own risk, but you better read yiqing95 comment.
-Steps to install phpseclib (modifying the library, not recommended now)-
(written on 2/Oct/2012, using Yii version 1.1.12. and phpseclib 0.3.0)
1) download phpseclib from: http://phpseclib.sourceforge.net
2) uncompress the downloaded archive, rename the folder to "phpseclib", and put it into your /vendors project directory.
3) rename all the files under /vendors/phpseclib/Crypt like this:
AES.php -> Crypt_AES.php
DES.php -> Crypt_DES.php
etc... (just prepend "Crypt_" in the file name)
4) search for "require_once" commands in those files and change them so they point to the new file names.
For example, in Crypt_AES.php change:
if (!class_exists('Crypt_Rijndael')) {
require_once 'Rijndael.php';
}
to:
if (!class_exists('Crypt_Rijndael')) {
require_once 'Crypt_Rijndael.php';
}
5) in config/main include phplib:
'import'=>array(
...
'application.vendors.phpseclib.Crypt.*',
),
6) now you can use phplib in your project. For example within a model you can use:
public function encrypt($text){
$cipher = new Crypt_AES();
$cipher->setPassword('anypassword');
return bin2hex($cipher->encrypt($text));
}
(see phplib documentation for more details)
should not rename the file name
the class and file name convention is compatible to Zend and PEAR . so you should use the ZendAutoLoader
and add some code like this
EZendAutoloader::$basePath = Yii::getPathOfAlias("application.vendors.phpseclib").'/'; EZendAutoloader::$prefixes = array( 'Crypt');
the original zendAutoloader is used as static ,but better as a instance thus we can set different basePath or make it support multiple basePath !
or for simple just extract every dir under the phpsecclib to the vendors directory(don't need to modify the zendAutoloader just register the prefixes) .
any way thanks for introduce it to us . and don't modify any 3rd library unless have to
modified zendAutoLoader:
class EZendAutoloader { /** * @var array class prefixes */ static $prefixes = array( 'Zend' ); /** * @var string path to where Zend classes root is located */ static $basePath = null; /** * @var array * --------------------------------- * you can specify multiple basePath eg: * array(Yii::getPathOfAlias('application.vendors.phpseclib'),Yii::getPathOfAlias('application.extensions.Net')...); * --------------------------------- */ static $basePaths = array(); /** * Class autoload loader. * * @static * @param string $class * @return boolean */ static function loadClass($className){ foreach(self::$prefixes as $prefix){ if(strpos($className, $prefix.'_')!==false){ if(empty(self::$basePaths)){ if(!self::$basePath) self::$basePath = Yii::getPathOfAlias("application.vendors").'/'; include self::$basePath.str_replace('_',DIRECTORY_SEPARATOR ,$className).'.php'; return class_exists($className, false) || interface_exists($className, false); }else{ $classLoaded = false ; foreach(self::$basePaths as $basePath){ include rtrim($basePath,'/\\'). DIRECTORY_SEPARATOR .str_replace('_',DIRECTORY_SEPARATOR ,$className).'.php'; if(class_exists($className, false) || interface_exists($className, false)){ return true ; } } return $classLoaded ; } } } return false; } }
Re: should not rename the filename
@yiqing95:
Very interesting, obviously I did not know about the zend and pear naming conventions. Thank you for pointing this out (I believe other people like me could make the same mistake in a desperate move to make a third party library work). I'll add a notice to the wiki pointing to your comment. Thank you!
Suggestion
nkd - why don't you rewrite the complete wiki so that instead leaving the "old" way of how not to do it you write about the "new" way of how to do it.
Re: Suggestion
Maurizio Domba: Yes. That is exactly what I am going to do but I need to try the new method first and then rewrite the whole wiki. The note I added is a temporal solution until I have the article written ;)
I am confused
I was writing the new version of the wiki but now I am a little bit confused. I downloaded the zendAutoloader extension and in the install instructions it says "Stripping all require_once from ZF. It is required for this extension and allows to load ZF classes faster."
So basically to run this extension you need comment out all the require_once in the zend (or in this case the phpseclib) libraries. Isn't this modifying the third party library also? I am starting to believe that my method of solving the issue is not that bad after all.
Using Pear in General
yiqing95, provides a great solution to not changing the name. I used it with PHPCAS by doing the following:
Copied the code he provided to EZendAutoloader.php
And put this in my controller file under the action I wanted.
Yii::import("ext.zendautoloader.EZendAutoloader", true); EZendAutoloader::$basePath = Yii::getPathOfAlias("application.vendors.CAS").'/'; // you can load not only Zend classes but also other classes with the same naming // convention EZendAutoloader::$prefixes = array( 'CAS'); Yii::registerAutoloader(array("EZendAutoloader", "loadClass"), true); require_once('CAS.php');
Worked like a charm.
Cheers!
include crypt_rsa.php: failed to open stream
Hi,
I followed all steps of this tutorial but I have this problem when I call a new instance of RSA.
My versions are:
Yii - 1.1.last
phpseclib - 0.3.5
the system show this error:
> #1 unknown(0):YiiBase::autoload("Crypt_RSA")
include(Math_BigInteger.php): failed to open stream: No such file or directory
Hi,
after a long time spend to solve my issues I know the correct vendor path (in my case) was vendor and not vendors.
So, I have followed all steps of this tutorial but I have this issue:
_include(MathBigInteger.php): failed to open stream: No such file or directory.
So, I think the problem is at line 464 of Crypt_RSA.php: if I remove
if (!class_exists('Math_BigInteger')) {
It works very fine. Why?
My versions are:
PHPseclib can also be used to upload multiple files to a remote server. In Symfony there is a component named Finder to do this. Is there is any such thing in Yii as well?
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.