Solved

duplication does not work when namespaces are involved

Posted on 2014-04-21
7
129 Views
Last Modified: 2014-04-22
I added code to matt zandstra php book

$classname2= "L520";
require_once("tasks/{$classname2}.php");
$classname2="tasks\\$classname2";

$myObj2= new $classname2();
$myObj2->doSpeak();
$myObj2->replicate();

listing 5.20
<?php
// TaskRunner.php
$classname = "Task";
require_once( "tasks/{$classname}.php" );
$classname = "tasks\\$classname";

$myObj = new $classname();
$myObj->doSpeak();
$myObj->replicate();
echo $myObj->property;

$classname2= "L520";
require_once("tasks/{$classname2}.php");
$classname2="tasks\\$classname2";

$myObj2= new $classname2();
$myObj2->doSpeak();
$myObj2->replicate();
?>

Open in new window


hello repeatproperty
Fatal error: Class 'tasks\L520' not found in C:\wamp\www\POPP-edition4-code\9781430260318_Chapter_05_Code\listing5.20.php on line 16


\tasks\Task.php
<?php
// Task.php
namespace tasks;

class Task {
  public $property='property';
    function doSpeak() {
        print "hello\n";
    }
    function replicate(){
      print "repeat";
    }
}
?>

Open in new window


so I added this file
\tasks\L520.php
<?php
  namespace L520;
    class L520{
      function dospeak(){
        
      }
      function replicate(){
        
      }
  }
?>

Open in new window



the way I learn is I create variables and classes and methods which I think do the exact same output

but with namespaces, this gets confusing and I get errors

maybe I have to declare
use new namespace
0
Comment
Question by:rgb192
  • 4
  • 3
7 Comments
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 40014274
Your problem is on line 14

$classname2="tasks\\$classname2";

Open in new window


Should be

$classname2="L520\\$classname2";

Open in new window


You are trying to instantiate the L520 class in the tasks namespace but you have declared the L520 class in the L520 namespace.

So either you need to change your class L520 to be in the tasks namespace

OR

Change your reference to the class to be the L520 namespace.
0
 

Author Comment

by:rgb192
ID: 40014741
I moved L520.php to new L520 folder


Code now works

<?php
// TaskRunner.php
$classname = "Task";
require_once( "tasks/{$classname}.php" );
$classname = "tasks\\$classname";

$myObj = new $classname();
$myObj->doSpeak();
$myObj->replicate();
echo $myObj->property;

$classname2= "L520";
require_once("L520/{$classname2}.php");
$classname2="L520\\$classname2";

$myObj2= new $classname2();
$myObj2->doSpeak();
$myObj2->replicate();
?>

Open in new window



but I do not understand the difference between
namespace
and
folder
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 40014853
A folder is where the file is actually stored and is at the filesystem level - not the PHP level.

A namespace is defined inside the php file to group classes, functions and variables under a common grouping.

Consider this example
<?php
require_once('tasks/person.php');
$x = new john\Person('Mary');
$y = new bob\Person('Jane');
?>

Open in new window

tasks/person.php
<?php
namespace john {
  class Person
  {
    function __construct($who)
    {
      echo "Hello $who, I am a John Person";
    }
  }
}
namespace bob {
  class Person 
  {
    function __construct($who)
    {
      echo "Hello $who, I am a Bob Person";
    }
  }
}
?>

Open in new window

Can you see that in the same file I have two namespaces (John and Bob)

Each of them has a class called person that do different things.

To avoid these two classes conflicting with each other I put them in different namespaces - that way I can differentiate between them without changing the underlying code of either of them.

Now consider this example
<?php
namespace john;
require_once('tasks/person.php');
$x = new Person('Mary');
?>

Open in new window

By declaring the namespace as john as the first line (it must be the first line) of the script the interpreter now looks for Person as John\Person by default.
Now look at the next example
<?php
namespace john;
require_once('tasks/person.php');
class People
{
  function __construct($who)
  {
    echo "Hullo $who I are a people";
  }
}
$x = new Person('Mary');
$y = new People('Frank');
?>

Open in new window

People also resolves correctly because it is part of the default namespace in which it is instantiated.

However the following will fail
<?php
namespace john;
require_once('tasks/person.php');
$x = new bob\Person('Mary');
?>

Open in new window

Why? Because the interpreter will attempt to find the class as
john\bob\Person - because we declared that the namespace we were using was John.
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:rgb192
ID: 40015182
A folder is where the file is actually stored and is at the filesystem level - not the PHP level.

is this like html browser view source and I see all the css/javascript files


and I can keep adding classes to namespace john whenever I call namespace john
<?php
namespace john;
require_once('tasks/person.php');
class People
{
  function __construct($who)
  {
    echo "Hullo $who I are a people";
  }
}
class another{
  function __construct($who){
    echo '<br>in class: '.__CLASS__.'<br>';
  }
}
$x = new Person('Mary');
$y = new People('Frank');
$z= new another('Richy');
?>

Open in new window




calling namespace bob works when namespace bob; is declared
<?php
namespace john;
require_once('tasks/person.php');
namespace bob;
$x = new Person('Mary');
?>

Open in new window


but is there a way to call with one line
$x = new ../bob/Person('Mary');
0
 
LVL 51

Accepted Solution

by:
Julian Hansen earned 500 total points
ID: 40015219
and I can keep adding classes to namespace john whenever I call namespace john
Slight correction - you don't call a namespace. A namespace is used by the interpreter to locate the correct code to run. You group all code you want together in a namespace that you optionally give a name. If you don't declare a namespace one is implied - the default namespace.
Think of a namespace as a packet of groceries. You put in the packet all the items you want to group to gether. To locate the item again you need to know what packet you put it in.

calling namespace bob works when namespace bob; is declared
That is because you overrode the previous namespace declaration.

but is there a way to call with one line
Not sure what you are asking - you can always find the namespace relative to the root
i.e
<?php
namespace john;
require_once('tasks/person.php');
$z = new Person('Mary'); // John person in the specified namespace so does not need John in front
$x = new \bob\Person('Jane'); // Bob person - found by referencing from the root.

Open in new window

0
 

Author Closing Comment

by:rgb192
ID: 40016191
$x = new \bob\Person('Jane'); // Bob person - found by referencing from the root.

now I know how to call a namespace from root
and where namespaces are located.

thanks
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 40016280
You are welcome - thanks for the points.
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Consider the following scenario: You are working on a website and make something great - something that lets the server work with information submitted by your users. This could be anything, from a simple guestbook to a e-Money solution. But what…
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

25 Experts available now in Live!

Get 1:1 Help Now