Good day, I wondered how you can call a part of the code (function, class) from another file in the PHP script. With relatively even small projects, it turns out that a lot of functions and classes accumulate. And if classes can somehow be separated into files (each file is separately for a class), then the functions need to be grouped. Actually the question is, who knows how to load a separate function without loading the whole file?

For example, the library file lib.php

<?php class DBconnect { private $host; private $user; private $pass; function connetctToDB(){ //...подключение к базе } //...другие методы } class Auth { private $login; private $pass; //... методы класса } //... Другие классы и функции ?> 

And in other files, for example, the same index.php does not use the include/require construction, but the option to load the definition of only one class or function. Any thoughts?

  • Found something here codeisart.ru/php-class-files-autoload is not quite sure what I wrote about, but also useful to read. It is rumored that __autoload will be abandoned with time, so ... We are exploring the issue further - DimKabuki

3 answers 3

For functions, I would do something like this:

We create a folder where all functions will be stored, if functions need to be broken down by context - we do it with folders, let's say for each function a separate file is created with its name, all we need to write is a class that will receive the path to the function and load, those. the result is something unpretentious of the form:

 /* singletone */ class Functions { const ROOT = '/functions/'; private static $_instance = null; private function __construct(){} private function __clone(){} public static function getInstance() { if( self::$_instance === null ) { self::$_instance = new self(); } return self::$_instance; } public function load( $path ) { $fullPath = $_SERVER['DOCUMENT_ROOT'] . self::ROOT . $path . '.php'; return file_exists( $fullPath ) ? include_once( $fullPath ) : false; } } 

And in addition, we use something like this

 Functions.getInstance()->load( 'view/form' ); // загрузим функцию form из группы view 

Well, in general, something like that, besides, this class could then be expanded, for example, add a method for loading any "group" as a whole, etc.

If we are talking about a kind of front controller for manipulating the form Functions::call('functionName', $param1, $param2) , then you need to look towards the PHP Closure functions. Those. do something like this (loading functions from files in this example is missing):

 class Functions { public static $methods = array(); // массива функций (Closure objects) public static function register( $functionName, $function ) { self::$methods[ $functionName ] = $function; } public static function call( $functionName ) { if( self::$methods[ $functionName ] ) { $func = self::$methods[ $functionName ]; $args = array_splice(func_get_args(), 1); return call_user_func_array( $func, $args ); } } } // пользоваться так, например Functions::register('hello', function($username){ echo 'Hello ' . $username; }); Functions::register('buy', function($username){ echo 'Buy ' . $username; }) Functions::call('hello', 'Vasya'); // -> hello Vasya Functions::call('buy', 'Vasya'); // -> buy Vasya 

Those. when writing any function, simply write it as:

 Functions::register('functionName', function() { // function code here... }); 

Thus, when inclusive, the function is registered in the static associative array of the class Functions and become available for calling the form

  Functions::call('functionName', param1, param2, param3, param4, ...); 

All you have to do is write the combination of functionality you need from the examples I gave to the class that would best suit you directly.

UPD

Regarding the method of proxying, you can simply write the __call function for the class and add a proxy small method for the Functions class:

 // метод класса Functions для облегчения проксирования public static function proxy( $name, $args ) { if( self::$methods[ $functionName ] ) { $func = self::$methods[ $functionName ]; return call_user_func_array( $func, $args ); } } // ну и пример класса class someClassName() { public function __call( $functionName, $args ) { Functions::call( $functionName, $args ); } } 

Now let's say we create an instance of this class. Suppose we have a registered function hello, while the class someClassName naturally does not have it, then:

 $obj = new someClassName(); $obj->hello( 1, 2, 3 ); // будет вызвана функция Functions::call('hello') // с параметрами 1, 2, 3 
  • Thank you for your reply. Mark it right. My knowledge does not yet allow me to fully and immediately realize how exactly to implement this example. But I understood the idea and now I will work in this direction. I'm just starting to plunge into the PLO and use it on real projects. While there is no opportunity to vote for an answer, I also recently visited the site. If everything works out, I will try to post my decision - DimKabuki
  • This is not as OOP as a non-standard solution. Please good luck learning. - Zowie

Alternatively, you can scatter functions on files and load them through the class loader (ibid and group). At the same time you will be able to control that the same file is not loaded twice.

  • one
    I already thought about that. All the same, there seems to be no such direct solution, it is necessary to create a separate file for each class, and it is easier to group the functions by purpose and also by files. Now I deal with the namespace. Just saw the “elegant solution” in CodeIgniter (framework), where you can place your libraries in the application / libraries directory, and then call them dynamically like this: $ this-> load-> library ('someclass'); You can of course deal with this framework, but I don’t like to drive myself into the “framework” :) and adjust the desired result or idea under the “template” - DimKabuki

Yes, actually here and so here http://php.net/manual/ru/function.spl-autoload.php

If you use accelerators, the inclusion of files will also be accelerated.

  • Gone to study. Accelerators hardly any of the hosters will give to deliver - DimKabuki
  • @DimKabuki and have not yet begun coding, I will say that functions can be done with static methods) That is, let's say there are text functions - you prescribe autoload, and you declare functions in something like class modules mytxt {public static function someFunc () {/ *. .. * /}} Then they can be loaded "modularly", and in the code you don't need to include anything, just the first call <? echo mytxt::someFunc($text) ?> <? echo mytxt::someFunc($text) ?> load this module itself. - Sh4dow
  • Thank. Just started on an autolod, on PHP.net.net they wrote: "spl_autoload_register () provides a more flexible alternative for automatic class loading. For this reason, using __autoload () is not recommended, and the function itself may no longer be supported or removed." Therefore, it was spl_autoload_register () that went to study. Although it is believed that it is still slower to include and require. As an option, I think about classes in separate files and functions as intended. Plus, you can organize a class for the connection depending on, say, the page id (i.e. only what is needed) - DimKabuki
  • Gone to study. Accelerators hardly any of the hosters will deliver. This is yes, because they themselves more and more often put them on their own. - Arni
  • @DimKabuki - naturally __autoload is slower than include . __autload is the so-called street magic and, naturally, works more slowly than the head-on solution in the form of include. Personally, in spite of everything, I think it is better to write 2-3 lines of code (my hands won’t fall off) than to tell the newcomer new colleagues how it works, why it is needed, etc. etc. (real story) - Zowie