mirror of
https://git.friendi.ca/friendica/friendica.git
synced 2025-06-07 21:24:27 +02:00
Add new documentation page about moving classes to src
This commit is contained in:
parent
70563e0324
commit
dfd4c8528e
7 changed files with 222 additions and 101 deletions
|
@ -24,14 +24,14 @@ For more info about PHP autoloading, please refer to the [official PHP documenta
|
|||
Let's say you have a PHP file in `src/` that define a very useful class:
|
||||
|
||||
```php
|
||||
// src/ItemsManager.php
|
||||
<?php
|
||||
namespace \Friendica;
|
||||
// src/ItemsManager.php
|
||||
<?php
|
||||
namespace Friendica;
|
||||
|
||||
class ItemsManager {
|
||||
public function getAll() { ... }
|
||||
public function getByID($id) { ... }
|
||||
}
|
||||
class ItemsManager {
|
||||
public function getAll() { ... }
|
||||
public function getByID($id) { ... }
|
||||
}
|
||||
```
|
||||
|
||||
The class `ItemsManager` has been declared in the `Friendica` namespace.
|
||||
|
@ -43,16 +43,16 @@ In order for the Composer autoloader to work, it must first be included. In Frie
|
|||
The code will be something like:
|
||||
|
||||
```php
|
||||
// mod/network.php
|
||||
<?php
|
||||
// mod/network.php
|
||||
<?php
|
||||
|
||||
function network_content(App $a) {
|
||||
$itemsmanager = new \Friendica\ItemsManager();
|
||||
$items = $itemsmanager->getAll();
|
||||
function network_content(App $a) {
|
||||
$itemsmanager = new Friendica\ItemsManager();
|
||||
$items = $itemsmanager->getAll();
|
||||
|
||||
// pass $items to template
|
||||
// return result
|
||||
}
|
||||
// pass $items to template
|
||||
// return result
|
||||
}
|
||||
```
|
||||
|
||||
That's a quite simple example, but look: no `require()`!
|
||||
|
@ -61,132 +61,137 @@ If you need to use a class, you can simply use it and you don't need to do anyth
|
|||
Going further: now we have a bunch of `*Manager` classes that cause some code duplication, let's define a `BaseManager` class, where we move all common code between all managers:
|
||||
|
||||
```php
|
||||
// src/BaseManager.php
|
||||
<?php
|
||||
namespace \Friendica;
|
||||
// src/BaseManager.php
|
||||
<?php
|
||||
namespace Friendica;
|
||||
|
||||
class BaseManager {
|
||||
public function thatFunctionEveryManagerUses() { ... }
|
||||
}
|
||||
class BaseManager {
|
||||
public function thatFunctionEveryManagerUses() { ... }
|
||||
}
|
||||
```
|
||||
|
||||
and then let's change the ItemsManager class to use this code
|
||||
|
||||
```php
|
||||
// src/ItemsManager.php
|
||||
<?php
|
||||
namespace \Friendica;
|
||||
// src/ItemsManager.php
|
||||
<?php
|
||||
namespace Friendica;
|
||||
|
||||
class ItemsManager extends BaseManager {
|
||||
public function getAll() { ... }
|
||||
public function getByID($id) { ... }
|
||||
}
|
||||
class ItemsManager extends BaseManager {
|
||||
public function getAll() { ... }
|
||||
public function getByID($id) { ... }
|
||||
}
|
||||
```
|
||||
|
||||
Even though we didn't explicitly include the `src/BaseManager.php` file, the autoloader will when this class is first defined, because it is referenced as a parent class.
|
||||
It works with the "BaseManager" example here and it works when we need to call static methods:
|
||||
|
||||
```php
|
||||
// src/Dfrn.php
|
||||
<?php
|
||||
namespace \Friendica;
|
||||
// src/Dfrn.php
|
||||
<?php
|
||||
namespace Friendica;
|
||||
|
||||
class Dfrn {
|
||||
public static function mail($item, $owner) { ... }
|
||||
}
|
||||
class Dfrn {
|
||||
public static function mail($item, $owner) { ... }
|
||||
}
|
||||
```
|
||||
|
||||
```php
|
||||
// mod/mail.php
|
||||
<?php
|
||||
// mod/mail.php
|
||||
<?php
|
||||
|
||||
mail_post($a){
|
||||
...
|
||||
\Friendica\dfrn::mail($item, $owner);
|
||||
...
|
||||
}
|
||||
mail_post($a){
|
||||
...
|
||||
Friendica\dfrn::mail($item, $owner);
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
If your code is in same namespace as the class you need, you don't need to prepend it:
|
||||
|
||||
```php
|
||||
// include/delivery.php
|
||||
<?php
|
||||
// include/delivery.php
|
||||
<?php
|
||||
|
||||
namespace \Friendica;
|
||||
namespace Friendica;
|
||||
|
||||
// this is the same content of current include/delivery.php,
|
||||
// but has been declared to be in "Friendica" namespace
|
||||
// this is the same content of current include/delivery.php,
|
||||
// but has been declared to be in "Friendica" namespace
|
||||
|
||||
[...]
|
||||
switch($contact['network']) {
|
||||
case NETWORK_DFRN:
|
||||
if ($mail) {
|
||||
$item['body'] = ...
|
||||
$atom = Dfrn::mail($item, $owner);
|
||||
} elseif ($fsuggest) {
|
||||
$atom = Dfrn::fsuggest($item, $owner);
|
||||
q("DELETE FROM `fsuggest` WHERE `id` = %d LIMIT 1", intval($item['id']));
|
||||
} elseif ($relocate)
|
||||
$atom = Dfrn::relocate($owner, $uid);
|
||||
[...]
|
||||
[...]
|
||||
switch($contact['network']) {
|
||||
case NETWORK_DFRN:
|
||||
if ($mail) {
|
||||
$item['body'] = ...
|
||||
$atom = Dfrn::mail($item, $owner);
|
||||
} elseif ($fsuggest) {
|
||||
$atom = Dfrn::fsuggest($item, $owner);
|
||||
q("DELETE FROM `fsuggest` WHERE `id` = %d LIMIT 1", intval($item['id']));
|
||||
} elseif ($relocate)
|
||||
$atom = Dfrn::relocate($owner, $uid);
|
||||
[...]
|
||||
```
|
||||
|
||||
This is the current code of `include/delivery.php`, and since the code is declared to be in the "Friendica" namespace, you don't need to write it when you need to use the "Dfrn" class.
|
||||
But if you want to use classes from another library, you need to use the full namespace, e.g.
|
||||
|
||||
```php
|
||||
// src/Diaspora.php
|
||||
<?php
|
||||
// src/Diaspora.php
|
||||
<?php
|
||||
|
||||
namespace \Friendica;
|
||||
namespace Friendica;
|
||||
|
||||
class Diaspora {
|
||||
public function md2bbcode() {
|
||||
$html = \Michelf\MarkdownExtra::defaultTransform($text);
|
||||
}
|
||||
class Diaspora {
|
||||
public function md2bbcode() {
|
||||
$html = \Michelf\MarkdownExtra::defaultTransform($text);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
if you use that class in many places of the code and you don't want to write the full path to the class every time, you can use the "use" PHP keyword
|
||||
|
||||
```php
|
||||
// src/Diaspora.php
|
||||
<?php
|
||||
namespace \Friendica;
|
||||
// src/Diaspora.php
|
||||
<?php
|
||||
namespace Friendica;
|
||||
|
||||
use \Michelf\MarkdownExtra;
|
||||
use \Michelf\MarkdownExtra;
|
||||
|
||||
class Diaspora {
|
||||
public function md2bbcode() {
|
||||
$html = MarkdownExtra::defaultTransform($text);
|
||||
}
|
||||
class Diaspora {
|
||||
public function md2bbcode() {
|
||||
$html = MarkdownExtra::defaultTransform($text);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that namespaces are like paths in filesystem, separated by "\", with the first "\" being the global scope.
|
||||
You can go deeper if you want to, like:
|
||||
|
||||
```
|
||||
// src/Network/Dfrn.php
|
||||
<?php
|
||||
namespace \Friendica\Network;
|
||||
// src/Network/Dfrn.php
|
||||
<?php
|
||||
namespace Friendica\Network;
|
||||
|
||||
class Dfrn {
|
||||
}
|
||||
class Dfrn {
|
||||
}
|
||||
```
|
||||
|
||||
Please note that the location of the file defining the class must be placed in the appropriate sub-folders of `src` if the namespace isn't plain `\Friendica`.
|
||||
Please note that the location of the file defining the class must be placed in the appropriate sub-folders of `src` if the namespace isn't plain `Friendica`.
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
// src/Dba/Mysql
|
||||
<?php
|
||||
namespace \Friendica\Dba;
|
||||
// src/Dba/Mysql
|
||||
<?php
|
||||
namespace Friendica\Dba;
|
||||
|
||||
class Mysql {
|
||||
}
|
||||
class Mysql {
|
||||
}
|
||||
```
|
||||
|
||||
So you can think of namespaces as folders in a Unix file system, with global scope as the root ("\").
|
||||
|
||||
## Related
|
||||
|
||||
* [Using Composer](help/Composer)
|
||||
* [How To Move Classes to `src`](help/Developer-How-To-Move-Classes-to-src)
|
Loading…
Add table
Add a link
Reference in a new issue