[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

duplication does not work when namespaces are involved

Posted on 2014-04-21
7
Medium Priority
?
153 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
7 Comments
 
LVL 59

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 59

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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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 59

Accepted Solution

by:
Julian Hansen earned 2000 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 59

Expert Comment

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

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

These days socially coordinated efforts have turned into a critical requirement for enterprises.
Many old projects have bad code, but the budget doesn't exist to rewrite the codebase. You can update this code to be safer by introducing contemporary input validation, sanitation, and safer database queries.
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…
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
Suggested Courses

649 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