extend-using-libs.md 5.54 KB
Newer Older
1 2 3
Using 3rd-Party Libraries
=========================

4
> Note: This section is under development.
Qiang Xue committed
5

6 7 8
Yii is carefully designed so that third-party libraries can be
easily integrated to further extend Yii's functionalities.

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
Using Packages Installed via Composer
-------------------------------------

Packages installed via Composer can be directly used in Yii without any special handling.


Using Downloaded Libraries
--------------------------

If a library has its own class autoloader, please follow its instruction on how to install the autoloader.

If a library does not have a class autoloader, you may face one of the following scenarios:

* The library requires specific PHP include path configuration.
* The library requires explicitly including one or several of its files.
* Neither of the above.

In the last scenario, the library is not written very well, but you can still do the following
work to make it work with Yii:

* Identify which classes the library contains.
* List the classes and the corresponding file paths in `Yii::$classMap`.

For example, if none of the classes in a library is namespaced, you may register the classes with Yii
like the following in the entry script after including `yii.php`:

```php
Yii::$classMap['Class1'] = 'path/to/Class1.php';
Yii::$classMap['Class2'] = 'path/to/Class2.php';
// ...
```

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67

Using Yii in 3rd-Party Systems
------------------------------

Yii can also be used as a self-contained library to support developing and enhancing
existing 3rd-party systems, such as WordPress, Joomla, etc. To do so, include
the following code in the bootstrap code of the 3rd-party system:

```php
$yiiConfig = require(__DIR__ . '/../config/yii/web.php');
new yii\web\Application($yiiConfig); // No 'run()' invocation!
```

The above code is very similar to the bootstrap code used by a typical Yii application
except one thing: it does not call the `run()` method after creating the Web application
instance.

Now we can use most features offered by Yii when developing 3rd-party enhancements. For example,
we can use `Yii::$app` to access the application instance; we can use the database features
such as ActiveRecord; we can use the model and validation feature; and so on.

Using Yii2 with Yii1
--------------------

Yii2 can be used along with Yii1 at the same project.
Since Yii2 uses namespaced class names they will not conflict with any class from Yii1.
However there is single class, which name is used both in Yii1 and Yii2, it named 'Yii'.
68
In order to use both Yii1 and Yii2 you need to resolve this collision.
69 70 71
To do so you need to define your own 'Yii' class, which will combine content of 'Yii' from 1.x
and 'Yii' from 2.x.

72 73 74 75
When using composer you add the following to your composer.json in order to add both versions of yii to your project:

```json
"require": {
76 77 78
    "yiisoft/yii": "*",
    "yiisoft/yii2": "*",
},
79 80
```

81
Start from defining your own descendant of [[yii\BaseYii]]:
82 83 84 85 86 87 88 89 90 91 92 93 94

```php
$yii2path = '/path/to/yii2';
require($yii2path . '/BaseYii.php');

class Yii extends \yii\BaseYii
{
}

Yii::$classMap = include($yii2path . '/classes.php');
```

Now we have a class, which suites Yii2, but causes fatal errors for Yii1.
95
So, first of all, we need to include `YiiBase` of Yii1 source code to our 'Yii' class
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
definition file:

```php
$yii2path = '/path/to/yii2';
require($yii2path . '/BaseYii.php'); // Yii 2.x
$yii1path = '/path/to/yii1';
require($yii1path . '/YiiBase.php'); // Yii 1.x

class Yii extends \yii\BaseYii
{
}

Yii::$classMap = include($yii2path . '/classes.php');
```

Using this, defines all necessary constants and autoloader of Yii1.
112
Now we need to add all fields and methods from `YiiBase` of Yii1 to our 'Yii' class.
113
Unfortunately, there is no way to do so but copy-paste:
114 115 116 117 118 119 120 121 122

```php
$yii2path = '/path/to/yii2';
require($yii2path . '/BaseYii.php');
$yii1path = '/path/to/yii1';
require($yii1path . '/YiiBase.php');

class Yii extends \yii\BaseYii
{
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
    public static $classMap = [];
    public static $enableIncludePath = true;
    private static $_aliases = ['system'=>YII_PATH,'zii'=>YII_ZII_PATH];
    private static $_imports = [];
    private static $_includePaths;
    private static $_app;
    private static $_logger;

    public static function getVersion()
    {
        return '1.1.15-dev';
    }

    public static function createWebApplication($config=null)
    {
        return self::createApplication('CWebApplication',$config);
    }

    public static function app()
    {
        return self::$_app;
    }

    // Rest of \YiiBase internal code placed here
    ...
148 149 150 151 152 153
}

Yii::$classMap = include($yii2path . '/classes.php');
Yii::registerAutoloader(['Yii', 'autoload']); // Register Yii2 autoloader via Yii1
```

154 155 156 157
Note: while copying methods you should NOT copy method "autoload()"!
Also you may avoid copying "log()", "trace()", "beginProfile()", "endProfile()"
in case you want to use Yii2 logging instead of Yii1 one.

158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
Now we have 'Yii' class, which suites both Yii 1.x and Yii 2.x.
So bootstrap code used by your application will looks like following:

```php
require(__DIR__ . '/../components/my/Yii.php'); // include created 'Yii' class

$yii2Config = require(__DIR__ . '/../config/yii2/web.php');
new yii\web\Application($yii2Config); // create Yii 2.x application

$yii1Config = require(__DIR__ . '/../config/yii1/main.php');
Yii::createWebApplication($yii1Config)->run(); // create Yii 1.x application
```

Then in any part of your program ```Yii::$app``` refers to Yii 2.x application,
while ```Yii::app()``` refers to Yii 1.x application:

```php
echo get_class(Yii::app()); // outputs 'CWebApplication'
echo get_class(Yii::$app); // outputs 'yii\web\Application'
177
```