PHP接口允许在接口中定义常量,例如
interface FooBar
{
const FOO = 1;
const BAR = 2;
}
echo FooBar::FOO; // 1
Run Code Online (Sandbox Code Playgroud)
任何实现类都将自动提供这些常量,例如
class MyFooBar implement FooBar
{
}
echo MyFooBar::FOO; // 1
Run Code Online (Sandbox Code Playgroud)
我对此的看法是,任何Global都是邪恶的.但我想知道接口常量是否同样适用.鉴于对接口的编码通常被认为是良好的做法,使用接口常量是在类上下文之外使用的唯一常量吗?
虽然我很想听听您的个人意见以及您是否使用界面常量,但我主要是在您的答案中寻找客观原因.我不希望这是一个民意调查问题.我对使用接口常量对可维护性有什么影响感兴趣.耦合.或单元测试.它与SOLID PHP有什么关系?它是否违反了任何被认为是PHP良好实践的编码原则?你明白了......
注意: Java有一个类似的问题列出了一些很好的理由,说明它们是Bad Practice,但由于Java不是PHP,我认为再次在PHP标记中提出它是合理的.
function foo () {
global $var;
// rest of code
}
Run Code Online (Sandbox Code Playgroud)
在我的小PHP项目中,我通常采用程序方式.我通常有一个包含系统配置的变量,当我需要在函数中访问此变量时,我会这样做global $var;.
这是不好的做法吗?
根据大多数编程语言范围规则,我可以访问在其中的函数外部定义的变量,但为什么这段代码不起作用?
<?php
$data = 'My data';
function menugen(){
echo "[".$data."]";
}
menugen();
?>
Run Code Online (Sandbox Code Playgroud)
有[]输出.
这(我的代码的简化版)不起作用:
<?php
$sxml = new SimpleXMLElement('<somexml/>');
function foo(){
$child = $sxml->addChild('child');
}
foo();
?>
Run Code Online (Sandbox Code Playgroud)
为什么?我想访问,$sxml因为我想在foo()失败时记录错误. foo()递归调用自己来创建一个目录列表,所以我担心将整体传递给$sxml自己(如同foo($sxml))可能会损害性能.
有没有办法进入$sxml内部$foo而不将其作为参数传递?(PHP 5.2.x +)
编辑:如果代码看起来像这样,实际上怎么办?
<?php
bar(){
$sxml = new SimpleXMLElement('<somexml/>');
function foo(){
$child = $sxml->addChild('child');
}
foo();
}
bar();
?>
Run Code Online (Sandbox Code Playgroud) 我有一个config.php包含在每个页面.在配置中我创建一个类似于下列的数组:
$config = array();
$config['site_name'] = 'Site Name';
$config['base_path'] = '/home/docs/public_html/';
$config['libraries_path'] = $config['base_path'] . '/libraries';
//etc...
Run Code Online (Sandbox Code Playgroud)
然后我有function.php,几乎每个页面都包括,我必须使用它global $config来访问它 - 这就是我想要摆脱的!
如何$config在不使用代码的情况下访问代码的其他部分global?
任何人都可以解释一下,为什么我不应该global在我的例子中使用?有人说这是一个糟糕的语气,其他人说它不安全?
我在何处以及如何使用它的示例:
function conversion($Exec, $Param = array(), $Log = '') {
global $config;
$cmd = $config['phppath'] . ' ' . $config['base_path'] . '/' . $Exec;
foreach ($Param as $s)
{
$cmd .= ' ' . $s;
}
}
Run Code Online (Sandbox Code Playgroud)
按照Vilx的建议,将所有这些放在类中会很酷但在这种情况下,我如何将它与从提取配置 …
所以我开始更深入地研究MVC(真正的MVC,而不是框架MVC),并且我正在尝试开发一个小框架.我正在阅读其他框架,如Symphony和Zend,看看他们是如何完成自己的工作,并尝试自己实现它.
我遇到的地方是URL路由系统:
<?php
namespace Application\Common;
class RouteBuilder {
public function create($name, $parameters) {
$route = new Route($name);
$route->resource = array_keys($parameters)[0];
$route->defaults = $parameters["defaults"];
$notation = $parameters["notation"];
$notation = preg_replace("/\[(.*)\]/", "(:?$1)?", $notation);
foreach ($parameters["conditions"] as $param => $condition) {
$notation = \str_replace($param, $condition, $notation);
}
$notation = preg_replace("/:([a-z]+)/i", "(?P<$1>[^/.,;?\n]+)", $notation);
//@TODO: Continue pattern replacement!!
}
}
/* How a single entry looks like
* "main": {
"notation": "/:action",
"defaults": {
"resource" : "Authentication",
},
"conditions": {
":action" : "(login)|(register)"
}
}, …Run Code Online (Sandbox Code Playgroud) 我有两个PHP文件.在第一个我基于$_GET值设置cookie ,然后调用一个函数,然后将该值发送到另一个文件.这是我在join.php中使用的一些代码:
include('inc/processJoin.php');
setcookie("site_Referral", $_GET['rid'], time()+10000);
$joinProc = new processJoin();
$joinProc->grabReferral($_COOKIE["site_Referral"]);
Run Code Online (Sandbox Code Playgroud)
然后,另一个文件(processJoin.php)将此值(以及其他文件)发送到将处理数据并将数据插入数据库的其他文件.
我遇到的问题是,当grabReferral()调用processJoin.php中的函数时,该$referralID变量未在全局范围内定义 - 其他函数processJoin.php似乎无法访问它以发送到其他文件/进程.
我在processJoin.php中试过这个:
grabReferral($rid) {
global $ref_id;
$ref_id = $rid;
}
someOtherFunction() {
sendValue($ref_id);
}
Run Code Online (Sandbox Code Playgroud)
但someOtherFunction似乎无法访问或使用该$ref_id值.我也尝试使用define()无济于事.我究竟做错了什么?
和同事讨论过这是不好的做法.现在我在网上找不到这个例子.
我们有很多数据库对象映射器,并且像这样调用它的函数
(示例) - setId方法获取数据库中的行并将其设置为预定义的属性
class Person {
public static function get($id) {
$object = new Person;
$object->setId($id);
return $object;
}
}
Run Code Online (Sandbox Code Playgroud)
像这样使用它我们可以使用这样的简单结构:(我们从例如一个帖子得到id)
$person = Person::get($id);
Run Code Online (Sandbox Code Playgroud)
代替
$person = new Person;
$person->setId($id);
Run Code Online (Sandbox Code Playgroud)
现在,我的直觉告诉我这是不好的做法.但我无法解释.也许有人在这里可以解释为什么这是,或者不是不好的做法
以下是我们如何使用它的一些其他示例.我们主要用它来吸气.(只是名称,而不是代码.几乎所有这些都只运行一个查询,它可以返回1个对象,然后使用结果的id来使用setId方法)
class CatalogArticle {
public static function get($id) { }
public static function getByArticlenumber($articlenumber) {} //$articlenumber is unique in the database
public static function getRandom() {} //Runs a query returning a random row
}
Run Code Online (Sandbox Code Playgroud) 为什么在像请求驱动的PHP这样的语言中难以测试单例或注册表模式?
除了实际的程序执行之外,您可以编写和运行测试,这样您就可以自由地影响程序的全局状态,并为每个测试函数运行一些拆卸和初始化,以使每个测试的状态达到相同状态.
我错过了什么吗?
有没有办法遍历一个对象来获取父对象数据?对于"父对象",我不是指父类,而是字面上的对象.这里有一个例子,在javascripty世界:-):
$parent->test = "hello world!";
$parent->child = new B();
Run Code Online (Sandbox Code Playgroud)
如果我可以访问子对象中父节点的所有数据,那就太好了:
class B{
//I know this doesn't exists, but it's what I wanted do do
function B(){
$this->parent = $this->parent();
echo $this->parent->test; //it would ouput "hello world"
}
}
Run Code Online (Sandbox Code Playgroud)
现在我的解决方案是将父对象传递给子对象(作为参考)或使父对象成为全局对象.你有更好的解决方案吗?
谢谢!