PHP - Globalize namespace contents - php

I can't find information related to it, the thing is that I have a namespace like this:
// foo.php
namespace foo;
function blah()
{
}
And then I include it / use it
require_once 'foo.php';
foo\blah();
Now I want to do the same but without specifying 'foo' all the time (something like using namespace in C++), is that possible?
require_once 'foo.php'
// using namespace foo;
blah(); // ?
Thank's!

Are you sure that the required file is in the same folder level with the file calling it? You can make some checks by throwing a simple if statement to verify.
$file_fnc = '/path/to/foo/file';
if(file_exists($file_fnc)) {
require_once $file_fnc;
} else {
echo "File not found";
}
This will help you determine if your file is truly existing. If it exists then we continue debugging from there. Test it and reply

Related

Undefined type 'Fromtify\Database\R'

I'm new to PHP. When working with namespaces, I ran into a problem with RedBeanPHP.
I have php script "db.php":
namespace Fromtify\Database {
require_once('../libs/rb-mysql.php');
class Contoller
{
public function Connect()
{
R::setup(
#My database settings here...
);
if (!R::testConnection()) {
echo 'Cant connect to database';
exit;
}
}
}
}
My IDE(VSCode) tells me: "Undefined type 'Fromtify\Database\R"
How can I solve the problem?
Thank you in advance
When you use namespaces, PHP will assume that any class you load is under that namespace as well, unless you've imported it.
Example:
namespace Foo;
$bar = new Bar;
This will assume that Bar also is under the namespace Foo.
If the class you're using is under another namespace, or not in a namespace at all (the global namespace), you need to tell PHP which class to use by importing it. You do this with the use
namespace Foo;
use Bar;
$bar = new Bar;
So in your case, it should be:
namespace Fromtify\Database {
use R;
R:setup(...);
// The rest of your code
}
Side note!_
Unless you have multiple namespaces in the same file, which you usually don't have, there's not need for the syntax:
namespace Foo {
// your code
}
You can simpy do:
namespace Foo;
// Your code.
...which makes the code a bit cleaner.
You can read more about defining namespaces and using namespaces in the manual

PHP can not create instance of class with namespace

I've got the following problem:
This is my super basic class:
class A
{
function foo()
{
echo "bar";
}
}
Now in front of the class declaration I use the following code:
$a = new A();
$a->foo();
When I open the php file in the browser, the output is "bar". Fine!
Now I want to do the same thing in another file.
directly in the first place I declare the following namespace:
namespace model\dbAction;
This is the path where my file with the class above is located.
So in another php file I do the following:
$a = new \model\dbAction\A();
$a->foo();
But I don't get any output and other code after that won't run so it looks like it breaks directly after the instancing of the class.
Any ideas why instancing the class in another file is not working?
Thanks!
Full code first php file:
<?php
namespace model\dbAction;
class A
{
function foo()
{
echo "bar";
}
}
Full code of the second file (which I call in the browser):
$a = new \model\dbAction\A();
$a->foo();
You still need to include the file -- providing the namespace itself will not include the file for you... unless you're using an autoloader. See: How do I use PHP namespaces with autoload?

What's wrong with this PHP code snippet I found? I get undefined variable 'obj'

I would like just to like to ask for a little elucidation about this three code snippets I found and how PHP behaves with them:
1) a php class (tmp.class.php) with a static method call:
<?php
class Dummy {
public function sayHello()
{
echo "HELLO FROM DUMMY";
}
public static function requireScript() {
require __DIR__ . "/tmp2.php";
}
}
Dummy::requireScript();
2) another file (tmp1.php), instantiating the previous defined class:
<?php
require_once __DIR__. "/tmp.class.php";
$obj = new Dummy;
?>
3) another file (tmp2.php), using the previous instance of the class:
<?php
require_once __DIR__ ."/tmp1.php";
$obj->sayHello();
?>
Now I know that as the requireScript() method has a require call in it, in fact the tmp2.php is included twice, am I right? But when I make the script run (open the tmp2.php file in the browser) I get a Notice: Undefined variable: obj and then of course a Fatal error because of the sayHello();
Shouldn't the $obj be available to the second required tmp2.php script? What is wrong with this code?
Thanks for attention!
In fact noone should build PHP application in that way. You shouldn't put require / include in many files. In simple application you should run require / include at the beginning of file to have everything you need. In more complex applications you should simple use Object Oriented Programming and use autoloader to load classes definitions when they are needed

Getting a 500 internal server error when implementing interface

I'm writing some dummy code to learn some design patterns. Therefore I made a class Duck.php that implements FlyBehavior. When I call the index.php, I see a blank page, and the console tells me, there is a 500 Internal Server Error. If I outcomment implenets FlyBehavior, the error disappears. So I guess I'm missing something about how to correctly implement an interface.
Thank you!
PHP 5.4.10
Duck.php
<?php
class Duck implements FlyBehavior
{
public function flyWithWings(){
echo 'foo';
}
}
FlyBehavior.php
<?php
interface FlyBehavior {
public function flyWithWings();
}
index.php
<?php
ini_set('error_reporting', E_ALL);
include 'Duck.php';
$duck = new Duck();
echo '<br>Test';
Your problem is that you didn't include the interface in the class that implements it, you can do that by require_once
Or an alternate to this is to use dependency management , for example check composer
<?php
require_once('FlyBehaviour.php');
class Duck implements FlyBehavior
{
public function flyWithWings(){
echo 'foo';
}
}
?>
If you hate having to require/include all the class library every time manually - like I do; perhaps __autoload may be of interest to you:
http://www.php.net/manual/en/function.autoload.php
Setup your scripts like this:
/ index.php
/ libs / FlyBehavior.php
/ libs / Duck.php
I.e. place all your classes in a folder called libs and then setup audoloader on index.php
So, your index.php will look like this:
<?php
// Constants
define('CWD', getcwd());
// Register Autoloader
if (!function_exists('classAutoLoader')) {
function classAutoLoader($class) {
$classFile = CWD .'/libs/'. $class .'.php';
if (is_file($classFile) && !class_exists($class))
require_once $classFile;
}
}
spl_autoload_register('classAutoLoader');
// Rest if your script
ini_set('error_reporting', E_ALL);
ini_set('display_error', 'On');
// Test
$duck = new Duck();
$duck->flyWithWings();
?>
Now, all the required classes are automatically loaded (when you instantiate them for the first time) - meaning you don't have to require any of the class files manually in your script.
Try it out; will save you tons of time :)

How Do Namespaces Work When Using SPL_AUTOLOAD_REGISTER?

I am learning how to use namespaces and autoloading in PHP today, and I appear to have hit a roadblock. Things seem to work when I don't use spl_autoload_register but instead require_once.
My folder structure is bare minimal:
- index.php
- class/
- Users.php
In my index.php file I have:
<?php
require_once('class/Users.php');
echo User::get(1);
In my class/Users.php file I have:
<?php
Class User {
function get($id) {
return $id;
}
}
and this works absolutely fine, returning the ID of 1
Ideally I will want to use an Autoload function and I discovered spl_autoload_* and this is what I tried to do, but with no success:
In my class/Users.php file I have:
<?php
namespace Users; // Added a namespace
Class User {
function get($id) {
return $id;
}
}
In my index.php file I have:
<?php
// Changed to using spl_autoload_register using an anonymous function to load the class
spl_autoload_register(function($class){
include('class/' . $class . '.php');
});
echo Users\User::get(1); // Added the Users namespace
but I get an error:
`Class 'Users\User' not found in /Applications/MAMP/htdocs/index.php on line 7`
Not really sure what I'm doing wrong.
I think you should add \ infront of the namespace path.
Example
\Users\User::get(1);
If you have to use a base path, like Traversable() you would also need to do
new \Traversable()
The autoloader is called with the full class name as an argument, including the namespace. In your example this is Users\User, so you end up doing
include('class/Users\User.php');
This fails because the class definition is not in a directory named Users (by the way, include would emit a warning that it cannot find the file which includes the expanded filename, and this warning would make things clearer -- do you have disabled error reporting?)
It's a probably a good idea to have the autoloader fail on the spot when the file is not found so that the failure mode is more apparent. For example you could change it to
require('class/' . $class . '.php'); // require will end the script if file not found
or to something like
$result = #include('class/' . $class . '.php'); // see documentation for include
if ($result === false) {
die("Could not include: 'class/$class.php'");
}

Categories