'PHP Pass variables with types from global namespace to included script
I want to pass some classes (with types!) from the global namespace to the included PHP scripts.
In my index.php file I initialize the classes OnlineUser and I18n. OnlineUser contains information about the logged in user, e.g. username and permissions. I use the class I18n for the translation of the webapp.
<?php
// All the include_once Statements
// ...
// All the use statements (namespaces of OnlineUser, I18n and so on)
// ...
if (!isset($_SESSION)) {
session_start();
}
$i18n = new I18n();
$user = new OnlineUser();
// Startpage
Route::add('/', function () {
global $user;
global $i18n;
include("../server/Views/Home.php");
});
A router class is then used to call the various views, which are of course PHP files themselves (with HTML). I took the router class from here.
This is my testing home view:
<?php
use \Language\I18n;
use \Services\Online\OnlineUser;
?>
<!DOCTYPE html>
<html lang="">
<head>
<?php include_once('../server/Views/Templates/Head.php'); ?>
<link rel="stylesheet" href="css/style.css">
<script src="js/fetch.js"></script>
</head>
<body>
<div><?php echo $i18n->translate(['user', 'name']); ?></div>
<div><?php echo $user->name; ?></div>
</body>
</html>
Of course I can use $user and $i18n in my ../server/Views/Home.php file. But, unfortunately, their types are not passed along.
Therefore, the autocomplete is missing in my VDE (Visual Studio Code + Intelephense). Of course I would like to get the autocomplete for these classes in my views as well.
So how can I pass variables from the global namespace with their types to my included PHP files?
- PHP 8.1.2
Solution 1:[1]
Since there's no way for the included file (or your IDE) to know in which context the view was included, there's no way for the IDE to be able to infer what those variables contains. The same view could be included in multiple different contexts, where the variables contains completely different values.
However, you could add a docblock to your views. In the top, add:
/**
* @var \Language\I18n $i18n
* @var \Services\Online\OnlineUser $user
*/
That's telling the IDE what type those variables contain.
Side note
It's generally recommended to avoid using global since it easily can lead to unexpected side effects, and be very hard to debug. There are alternative ways of passing variables to your callbacks, like using use():
Route::add('/', function () use($i18n, $user){
include("../server/Views/Home.php");
});
You can read more about the differences in this answer:
Difference between 'use()' or 'global' to access a global variable in a closure?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
