Solved

duplication does not work when namespaces are involved

Posted on 2014-04-21
7
135 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 55

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 55

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
Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

 

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 55

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 55

Expert Comment

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

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
two ways encryption with php 3 37
Dynamic Dropdowns 15 32
Row insertion failed. Array 5 46
Wordpress Only run code if on a certain page 11 22
Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
Introduction This article is intended for those who are new to PHP error handling (https://www.experts-exchange.com/articles/11769/And-by-the-way-I-am-New-to-PHP.html).  It addresses one of the most common problems that plague beginning PHP develop…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
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.

839 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