Variabele classname werkt niet
Code (php)
1
2
3
4
5
2
3
4
5
<?php
namespace Library\Framework\Config;
$this->adapter = new Adapter\Ini($options);
?>
namespace Library\Framework\Config;
$this->adapter = new Adapter\Ini($options);
?>
En dit werkt niet (hier neemt hij de namespace niet over, dus ipv Library\Framework\Config\Adapter\Ini word het Adapter\Ini:
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<?php
namespace Library\Framework\Config;
$adapter = 'Adapter\Ini';
$this->adapter = new $adapter($options);
?>
namespace Library\Framework\Config;
$adapter = 'Adapter\Ini';
$this->adapter = new $adapter($options);
?>
Waarom werkt de tweede manier niet? Want ik wil met adapters werken zodat ik mijn config kan inlezen via bv csv, xml, ini zonder dat ik het complete script hoef te veranderen..
Gewijzigd op 20/08/2012 15:49:23 door Joakim Broden
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<?php
namespace Library\Framework\Config;
$adapter = 'Adapter\\Ini';
$this->adapter = new $adapter($options);
?>
namespace Library\Framework\Config;
$adapter = 'Adapter\\Ini';
$this->adapter = new $adapter($options);
?>
Gewijzigd op 20/08/2012 15:56:39 door John Berg
Nee dat werkt ook niet
Het enige wat ik nog kan bedenken is dat de namespace Adapter relatief in de namespace Library\Framework\Config niet bestaat, maar dan zou het eerste voorbeeld ook niet werken.
Ik doe in mijn code:
Code (php)
1
2
3
4
2
3
4
$modelclass = '\\Ganymedes\\MVC\Models\\' . $this->router->controller;
if( class_exists( $modelclass ))
$model = new $modelclass();
if( class_exists( $modelclass ))
$model = new $modelclass();
Werkt als een zonnetje. Het enige verschil met jouw code is dat ik een absolute namespace opgeef.
Ja maar het gekke is als 'Adapter\Ini' doe doet hij het wel, maar als ik 'Adapter\Ini' eerst opsla in een variable dan doet hij het weer niet...
Dit werkt:
Code (php)
1
2
3
4
5
2
3
4
5
<?php
namespace Library\Framework\Config;
$this->adapter = new Adapter\Ini($options);
?>
namespace Library\Framework\Config;
$this->adapter = new Adapter\Ini($options);
?>
Dit werkt ook:
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<?php
namespace Library\Framework\Config;
$adapter = __NAMESPACE__.'Adapter\Ini';
$this->adapter = new $adapter($options);
?>
namespace Library\Framework\Config;
$adapter = __NAMESPACE__.'Adapter\Ini';
$this->adapter = new $adapter($options);
?>
Dit werkt niet:
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<?php
namespace Library\Framework\Config;
$adapter = 'Adapter\Ini';
$this->adapter = new $adapter($options);
?>
namespace Library\Framework\Config;
$adapter = 'Adapter\Ini';
$this->adapter = new $adapter($options);
?>
Waarom neemt hij bij de laatste de namespace 'Library\Framework\Config' niet over?
Gewijzigd op 21/08/2012 17:55:06 door Joakim Broden
Op 20-8 om 17:12 schreef ik al dat namespaces ook relatief t.o.v. elkaar of absoluut kunnen worden aangegeven. Ik gebruik uitsluitend absolute namespaces dus met een ' \' aan het begin, om net als bij includes niet te hoeven bijhouden waar ik sta.
Overigens moet je een '\' in een string escapen, dus als je een string met waarde '\' wil hebben dan doe je '\\'
Foutmelding is dat mijn autoloader de class niet kan vinden aangezien hij de namespace niet overneemt. Het klopt dat je absolute paden kan geven en dat doe ik momenteel nu ook alleen ik wil weten WAAROM php de namespace niet overneemt bij een variabele class naam.
n.b. zoals ik al eerder zei: namespaces hebben niets van doen met het onderliggende file systeem!!
En dit komt regelrecht uit mijn code:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<?php
namespace Library\Framework\Config;
class ConfigFactory {
/**
* Avaible config file extentions.
*
* @acces protected.
* @var array.
*/
protected static $extensions = array(
'ini' => 'Ini',
'csv' => 'Csv',
'xml' => 'Xml',
'json' => 'Json'
);
/**
* Load a config file.
*
* @acces public.
* @param string $filename. The config file.
* @param boolean $return. Return as config object.
* @return array|object. If $return is true return config object, return array if false.
*/
public static function loadConfigFromFile($filename, $return = false) {
$pathinfo = pathinfo($filename);
if (!isset($pathinfo['extension'])) {
throw new Exception\RuntimeException(sprintf('Failed to initialize %s, filename "%s" is missing an extension and cannot be auto-detected.', __CLASS__, $filename));
}
$extension = strtolower($pathinfo['extension']);
if ($extension === 'php') {
if (!is_file($filename) || !is_readable($filename)) {
throw new Exception\RuntimeException(sprintf('Failed to initialize %s, file "%s" does not exist or is not readable.', __CLASS__, $filename));
}
$config = include $filename;
} elseif (isset(self::$extensions[$extension])) {
$reader = 'Reader\\'.self::$extensions[$extension];
$reader = new $reader(); // Werkt niet...
//$reader = __NAMESPACE__.'\\Reader\\'.self::$extensions[$extension];
//$reader = new $reader(); //Werkt wel
//$reader = new Reader\Ini(); \\ Werkt wel
$config = array();
} else {
throw new Exception\RuntimeException(sprintf('Failed to initialize %s, unsupported config file extension: .%s.', __CLASS__, $pathinfo['extension']));
}
return ($return) ? new Config($config) : $config;
}
}
?>
namespace Library\Framework\Config;
class ConfigFactory {
/**
* Avaible config file extentions.
*
* @acces protected.
* @var array.
*/
protected static $extensions = array(
'ini' => 'Ini',
'csv' => 'Csv',
'xml' => 'Xml',
'json' => 'Json'
);
/**
* Load a config file.
*
* @acces public.
* @param string $filename. The config file.
* @param boolean $return. Return as config object.
* @return array|object. If $return is true return config object, return array if false.
*/
public static function loadConfigFromFile($filename, $return = false) {
$pathinfo = pathinfo($filename);
if (!isset($pathinfo['extension'])) {
throw new Exception\RuntimeException(sprintf('Failed to initialize %s, filename "%s" is missing an extension and cannot be auto-detected.', __CLASS__, $filename));
}
$extension = strtolower($pathinfo['extension']);
if ($extension === 'php') {
if (!is_file($filename) || !is_readable($filename)) {
throw new Exception\RuntimeException(sprintf('Failed to initialize %s, file "%s" does not exist or is not readable.', __CLASS__, $filename));
}
$config = include $filename;
} elseif (isset(self::$extensions[$extension])) {
$reader = 'Reader\\'.self::$extensions[$extension];
$reader = new $reader(); // Werkt niet...
//$reader = __NAMESPACE__.'\\Reader\\'.self::$extensions[$extension];
//$reader = new $reader(); //Werkt wel
//$reader = new Reader\Ini(); \\ Werkt wel
$config = array();
} else {
throw new Exception\RuntimeException(sprintf('Failed to initialize %s, unsupported config file extension: .%s.', __CLASS__, $pathinfo['extension']));
}
return ($return) ? new Config($config) : $config;
}
}
?>
en roep het zo aan:
Foutmelding is dat hij de 'Adapter\Ini.php' met de ini class niet kan vinden. In mijn autoloader kan ik zien dat hij de namespace niet overneemt terwijl dat normaal wel is. Normaal krijgt mijn autoloader de classes zo binnen 'Library\Framework\Config\Adapter\Ini' alleen nu krijg ik hem als 'Adapter\Ini' binnen met gevolg dat de class niet bestaat.
Gewijzigd op 22/08/2012 10:40:24 door Joakim Broden
Wat zie je dan?
Ik begrijp dus dat de namespace van je reader Library\Framework\Config\Adapter is, m.a.w. een sub van de namespace van je loader. In dat geval zou ik ervoor gaan om de absolute namespace naam te gebruiken, m.a.v. de code zoals die in regel 45 staat.
Maar kan iemand mij misschien de logica/nut uitleggen van waarom hij de namespace niet overneemt?
Hertog Jan op 22/08/2012 10:40:04:
Maar kan iemand mij misschien de logica/nut uitleggen van waarom hij de namespace niet overneemt?
Maar kan iemand mij misschien de logica/nut uitleggen van waarom hij de namespace niet overneemt?
De korte versie komt er op neer dat als je een namespace gebruikt, je die altjd in een bepaalde context moet zien.
Als ik namespace Lib\Test declareer en vervolgens code runt dan gebeurt dat in de context van de huidge namespace.
Zou ik de constante PDO::FETCH_ASSOC willen gebruiken dan zal dat een foutmelding geven omdat Lib\Test\PDO::FETCH_ASSOC niet bestaat. De class constant bestaat namelijk binnen de root namespace en moet dus aangeroepen worden als \PDO::FETCH_ASSOC
Helemaal erg wordt het als ik dit ga doen:
namespace Lib\Test
..
include 'proefje.php' (binnen proefje staat namespace Proef;)
mijn context is nu Lib\Test\Proef
maar als ik dit doe:
namespace Lib\Test
..
include 'proefje.php' (binnen proefje staat namespace \Proef;)
dan is mijn context \Proef
Op deze manier werken is foutgevoelig, als je proef.php veranderd, veranderd ook de context binnen het bestand waarin proef.php geinclude wordr.
Om dat te voorkomen werk ik altijd met absolute namespaces. (net als ik altijd met absolute file paden werk)