PHP Variable Scope Inside Included Files - php

I have the following code:
<?php
session_start();
require_once('ClassFile.php');
use ClassFile\Component;
include 'somefile.php';
?>
Within this template I can access properties of the Component (e.g. $comp = new Component();). However, Component is not visible from within somefile.php. I get an error to the effect that it does not exist. The (poor) workaround is to copy the same code in somefile.php. Can anyone say what's going on? Do I need to somehow globalize the items in the require_once and use statements? Thanks.

If you mean that you cannot do new Component inside somefile.php, that's because the class is called ClassFile\Component, not Component. The use alias does not extend to included files. If you want to alias ClassFile\Component to Component in somefile.php too, you have to write the appropriate use statement in that file too.
Namespacing is always per-file.

Related

How do I resolve missing class function in codeigniter?

I have this in my controller:
if (!defined('BASEPATH'))
exit('No direct script access allowed');
use xampp\htdocs\client\vendor\phpoffice\phpspreadsheet\src\PhpSpreadsheet\Spreadsheet;
use xampp\htdocs\client\vendor\phpoffice\phpspreadsheet\src\PhpSpreadsheet\Writer\Xlsx;
But here is the error I am seeing after running the code
Message: Class 'xampp\htdocs\client\vendor\phpoffice\phpspreadsheet\src\PhpSpreadsheet\Spreadsheet' not found
Filename: C:\xampp\htdocs\client\application\controllers\admin\Home.php
You appear to have confused use and include/require.
A use statement is for namespace importing and aliasing. It says "when I use the class name Foo, what I actually mean is Something\Something\Foo. That full name may look like a Windows file path, but the \ here is actually PHP's namespace separator, and doesn't directly relate to the location on disk.
In this case, you would write:
// Alias these class name so I don't have to write them in full in this file
use PhpSpreadsheet\Spreadsheet;
use PhpSpreadsheet\Writer\Xlsx;
If you want to reference the code in a particular file, you need the include and require family of keywords. Those say "load this PHP file, and execute the code in it, including class and function definitions.
So the following would make sense:
// Load the file
require_once 'xampp\htdocs\client\vendor\phpoffice\phpspreadsheet\src\PhpSpreadsheet\Spreadsheet.php';
require_once 'xampp\htdocs\client\vendor\phpoffice\phpspreadsheet\src\PhpSpreadsheet\Writer\Xlsx.php';
However, most PHP libraries are built to be autoloaded, so you don't have to name each file manually. Generally, you don't even need to configure the autoloading itself, instead you'd use Composer to install them, and it would set up the autoloader for you.
You would then write, in the main entry point of your code:
require_once 'vendor/autoload.php';
And the classes would be loaded automatically when referenced. Note that you probably still want the use lines, though, and those do have to be in each file (because each file can use the same alias to reference different classes).

Have a class access another class that has been defined after that first class?

In PHP, is it at all possible to have a class access another class, that has been defined later in the code?
require_once class_common_functions.php
require_once class_display_page.php
require_once class_specific_functions.php
require_once class_parse_data.php
What I'm trying to achieve is, class_display_page -> class_common_functions -> class_parse_data -> class_specific_functions.
I could reorder these four,
require_once class_specific_functions.php
require_once class_parse_data.php
require_once class_common_functions.php
require_once class_display_page.php
But then I would like class_specific_functions and class_parse_data to have access to class_common_functions as well.
I'm not too sure how to do this? Any suggestions? I'm currently accessing classes from classes using the class contructor, but for that to work the classes have to be in a certain order.
I'm probably approaching this wrong. I'm used to developing simpler web sites, trying to learn.
No, it is not possible to have a class access another class, that has been defined later in the code (assuming later to be code that's loaded later). To use a class (access it's static methods/properties or instantiate it), the class file must be loaded before trying to use it. You get around having to micro-manage this by using autoloading.
However, within the same file you define a class later in the file and access it at the begining
Here is an overview of autoloading: http://www.php.net//manual/en/language.oop5.autoload.php

Where can I put my global code in Kohana 3.3?

Say I want a constant, a function or a class to be available in all my models, views and controllers code (within a particular web site (application)). Where can I put them? I don't mind importing them explicitly in every file I need them in but I don't know how (simple require_once does not seem to work).
You can put them in the vendor folder (in application/vendor or modules/MOD/vendor). Then you can load it like this:
require Kohana::find_file('vendor', 'folder/file','ext');
You can read up more on this in the user guide
Now, it should be stated you should in general not use functions or globals.
I declare Constants in Bootstrap.php and create my own Helpers for general functions under application/classes/Helpers.
If you need to integrate a third party library into Kohana or want to make code available to other Kohana users consider creating a module instead.
You can define all your constants in new php file and place it in the application/classes directory. In your Template controller or in the main controller like Welcome or Website, just place the code in the __constructor()
require_once Kohana::find_file( 'classes', 'filename' );
I suggest you to put your constant variables in the bootstrap.php file because this is loaded by the framework before every request.
You can simply put your classes in the root of the classes directory, the framework will find.
This worked well for me...
In application/config/constants.php:
define('SOME_COOL_CONSTANT', 'foo');
return array();
In index.php:
Kohana::$config->load('constants');
SOME_COOL_CONSTANT should then be available globally.

Using php namespaces properly

I am trying to figure out how to use the namespace in php. I have been reading about how to use it and for some reason I can not get it to work. I have two files one which I have stored in Applications/Database/Classes file name is DatabaseConnection.php and the other in the root directory called DB.phpinside the DatabaseConnection.php file I have the following code:
<?php
function hello()
{
echo "hello";
}
?>
This is the DB.php file contents:
<?php
namespace Applications\Database\Classes;
ini_set('display_errors', true);
hello();
?>
Maybe I am completely missing how to use it properly but if I set a namespace is that the same as using include or require? I might be completely misunderstanding how to use it. I am new to OOP and have never heard of namespaces until I started trying to learn OOP? Can someone point out what I did wrong.
Namespaces are for organizing your code in so that you can divide components up and help with the readability. For example if I have a class Pittbull and another Dashund I can place them into a namespace like so for organization:
Animals.Dogs.Pittbull
Animals.Dogs.Dashund
This also helps with potential collisions like the below:
Animals.Dogs.Misc
Animals.Cats.Misc
The Misc class exists twice in this instance, but instead of there being a conflict of which Misc to use, you can use the same class name for both classes (and have different properties and methods inside of them) and not have a conflict of which one you want to use.
The require keyword is a completely different concept and is used to load actual files into the executing script.
Instruction how to use autoloading in PHP (PSR-0):
https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md

PHP class referencing confusion across multiple files

I have an index.php file that has 3 includes
<?php
require_once('mod.php');
$mod = new Mod();
require_once('start.php');
require_once('tools.php');
....some code....
?>
I need to be able to reference the $mod object inside the start.php and tools.php.
How do I pass that object to be referenced by those 2 other require files?
Basically the mod.php is a class that has an array list generated in its __construct(). I want to use that array list data inside the startup.php and tools.php file but not sure how to pass in the existing one without calling "new" inside both of those files separately which doesn't do what I need since it resets everything.
Thanks!
It looks like you're using require() calls not for dynamic functionality loading (get a class definition in), but as something like a function call. Don't. Avoid global variables like a plague.
Side note: Instead of worrying about doing the require() calls in the right order to get your classes defined, I'd encourage you to look at Autoload functionality in PHP 5. It allows you to define which classes are defined in which file, and load those files on-demand when the classes are requested.
First of all use some autoloader. Dozens of require on the top of the file are annoying and needless.
You don't have to pass any references to other files. require works like "copy-paste-execute" so $mod will be available in that file.
#index.php
$mod = new Mod();
include 'file.php';
#file.php
$mod->doSth(); // works file!
Your problem is probably variable scope. If you need to use $mod inside another object (the fact that its source (class) is in another file doesn't matter) pass reference to $mod as a constructor argument, pass it using a special setter ($obj->setMod($mod); $obj->doSth();) or use more complex but better solution like Dependency Injection Container (sample implementation).
Doing require (or require_once, include, or include_once), simply includes and evaluates the code. The variable scope is inherited from the point at which the code is imported.
As an example, using your code:
<?php // index.php
require_once('mod.php');
$mod = new Mod();
require_once('start.php');
And the include:
<?php // start.php
$mod->arrayList(); // $mod is the object created in index.php
The mod should be available in those other files...if you need it in a function or class, use the global keyword, like:
function test() {
global $mod;
print $mod->list;
}

Categories