-2

I'm trying to understand namespaces and include in PHP, and came up with an example that looks like this:

$ tree test/class/
test/class/
├── Bar.php
└── testin.php

Here are the bash commands I'm running to set up the example:

mkdir -p test/class

cat > test/class/Bar.php <<EOF
<?php
namespace Foo;
class Bar {
  function __construct() { // php 5 constructor
    print "In Bar constructor\n";
  }
  public function Bar() { // php 3,4 constructor
    echo "IT IS Bar\n";
  }
}
?>
EOF

cat > test/class/testin.php <<EOF
<?php
use Foo;
require_once (__DIR__ . '/Bar.php');
$bar = new Bar();
?>
EOF

pushd test/class
php testin.php
popd

And when I run this I get:

+ php testin.php
PHP Warning:  The use statement with non-compound name 'Foo' has no effect in /tmp/test/class/testin.php on line 2
PHP Parse error:  syntax error, unexpected '=' in /tmp/test/class/testin.php on line 4

Ok, so how could I modify this example, so it testin.php reads the class in Bar.php and instantiates an object out of it, while using use and namespaces?


EDIT: The second file setup should have the "EOF" quoted, because of presence of dollar sign $:

cat > test/class/testin.php <<"EOF"
<?php
use Foo;
require_once (__DIR__ . '/Bar.php');
$bar = new Bar();
?>
EOF

... then running the php scripts gives the error:

+ php testin.php
PHP Warning:  The use statement with non-compound name 'Foo' has no effect in /tmp/test/class/testin.php on line 2
PHP Fatal error:  Class 'Bar' not found in /tmp/test/class/testin.php on line 4

EDIT2: If I declare the full path, beginning with \ which signifies the root namespace, then it works:

cat > test/class/testin.php <<"EOF"
<?php
use \Foo;
require_once (__DIR__ . '/Bar.php');
$bar = new \Foo\Bar();
?>
EOF

... then everything works:

+ php testin.php
In Bar constructor

... but then, what is the point of use, if I have to repeat the full namespace path when doing $bar = new \Foo\Bar();? (if I don't explicitly write \Foo\Bar(), then class Bar cannot be found...)

Community
  • 1
  • 1
sdaau
  • 36,975
  • 46
  • 198
  • 278
  • 1
    Why the bash commands and not just the PHP source? And why put the correction into an appendix and not modify the code directly? That makes it all very verbose and unclear. – syck Apr 07 '16 at 08:48
  • Thanks @syck - The `bash` commands are there so that readers here could exactly reconstruct what I'm doing, I guess.. And I added correction in appendix so one can follow what my mistakes are - I had a hard time finding an example that explains this, so I think it is useful to jot down where one can go wrong... Cheers! – sdaau Apr 07 '16 at 08:52
  • 1
    I guess what you want to find out is that you have to use the `namespace` operator in the calling as well as in the callee class. `use` defines aliases. – syck Apr 07 '16 at 08:59
  • 1
    And I still do not understand where the benefit for the reader is from the fact, that you do not know how to use heredoc in bash. The question is not tagged bash and there are many questions where this is answered in a more sensible way, like http://stackoverflow.com/questions/4937792/using-variables-inside-a-bash-heredoc – syck Apr 07 '16 at 09:05
  • Thanks again @syck - correct, my question boiled down to why "use the `namespace` operator in the calling as well as in the callee class", and thanks for the answer. As far as the `bash` goes, the idea was that the reader could just copy paste and reconstruct the files for testing; I left the quoting error I made, because I didn't find a reference to `syntax error, unexpected '=' in...` anywhere when I got it first - had I known it could occur due to quoting errors like this, I could have fixed it earlier. Cheers! – sdaau Apr 07 '16 at 09:14
  • http://php.net/manual/en/language.namespaces.importing.php hope this will clear the confusion – Chetan Ameta Apr 07 '16 at 09:23
  • `use` *aliases* names to shorter local names; that should explain why `use Foo` does nothing. `use` does not "import" all contents of a namespace or any such thing, which you seem to expect. – deceze Apr 07 '16 at 09:29

1 Answers1

0

if you use use Foo\Bar; in your testin.php file, then you can use $bar = new Bar(); directly.

if you use $bar = new Foo\Bar();, you don't need add use ...

Because use Foo just means the namespace(in your case it means the folder 'class'), if you want it corresponds an appointed file, you should add the file's name.

gdreamlend
  • 108
  • 9