可能重复:
魔术方法是PHP的最佳实践吗?
这些都是简单的例子,但想象一下你的班级中有两个以上的属性.
什么是最佳做法?
a)使用__get和__set
class MyClass {
private $firstField;
private $secondField;
public function __get($property) {
if (property_exists($this, $property)) {
return $this->$property;
}
}
public function __set($property, $value) {
if (property_exists($this, $property)) {
$this->$property = $value;
}
}
}
$myClass = new MyClass();
$myClass->firstField = "This is a foo line";
$myClass->secondField = "This is a bar line";
echo $myClass->firstField;
echo $myClass->secondField;
/* Output:
This is a foo line
This is a bar line
*/
Run Code Online (Sandbox Code Playgroud)
b)使用传统的二传手和吸气剂
class MyClass {
private $firstField; …Run Code Online (Sandbox Code Playgroud) 我来自php世界.你能解释一下getter和setter是什么,可以给你一些例子吗?
除非我完全弄错了,否则这些__get和__set方法应该允许重载→ get和set.
例如,以下语句应调用该__get方法:
echo $foo->bar;
$var = $foo->bar;
Run Code Online (Sandbox Code Playgroud)
以下应该使用该__set方法:
$foo->bar = 'test';
Run Code Online (Sandbox Code Playgroud)
这在我的代码中不起作用,并且可以通过这个简单的示例重现:
class foo {
public $bar;
public function __get($name) {
echo "Get:$name";
return $this->$name;
}
public function __set($name, $value) {
echo "Set:$name to $value";
$this->$name = $value;
}
}
$foo = new foo();
echo $foo->bar;
$foo->bar = 'test';
echo "[$foo->bar]";
Run Code Online (Sandbox Code Playgroud)
这只会导致:
[test]
Run Code Online (Sandbox Code Playgroud)
die()在那里打几个电话表明它根本没有打它.
现在,我只是说它,并且我手动使用__get它现在需要的地方,但这不是非常动态,并且需要知道"重载"代码实际上没有被调用,除非特别调用.我想知道这是不应该以我理解它应该或为什么这不起作用的方式起作用.
这是在运行php 5.3.3.
有人可以向我解释为什么这段简单的代码不起作用?
var user = {
get name() {
return this.name;
},
set name(value) {
this.name = value;
}
};
user.name = 'David';
Run Code Online (Sandbox Code Playgroud)
当我把它放在Firefox 21.0的Firebug控制台中时,它给了我这个错误:
InternalError: too much recursion
this.name = value;
Run Code Online (Sandbox Code Playgroud)
为什么?在Javascript中定义getter和setter的正确方法是什么?
我有一个 Laravel 7 项目,需要在显示之前将大量数据从模型转换为视图。
我想过使用Laravel Accessors并直接在我的blade.php 文件中使用它们。
但是当我处理完一个简单的 html 表时,我查看了我的代码,我认为访问器太多了,甚至其中一些访问器的名称难以阅读。
@foreach($races as $race)
<tr>
<td>{{ $race->display_dates }}</td>
<td>{{ $race->display_name }}</td>
<td>{{ $race->type->name }}</td>
<td>{{ $race->display_price }}</td>
<td>{{ $race->display_places }}</td>
<td>{{ $race->online_registration_is_open ? 'Yes' : 'No' }}</td>
</tr>
@endforeach
Run Code Online (Sandbox Code Playgroud)
public function show(Group $group)
{
$races = $group->races;
$races->loadMissing('type'); // Eager loading
return view('races', compact('races'));
}
Run Code Online (Sandbox Code Playgroud)
// Accessors
public function getOnlineRegistrationIsOpenAttribute()
{
if (!$this->online_registration_ends_at && !$this->online_registration_starts_at) return false;
if ($this->online_registration_ends_at < now()) return false;
if ($this->online_registration_starts_at > …Run Code Online (Sandbox Code Playgroud) 我已经四处搜索但是在PHP类中使用$ this时找不到确定的答案(如果有的话).我仍然试图使用OOP方法来解决问题,并希望确保我使用最佳实践.
所以我的问题是你应该如何以及何时定义变量以及何时应该使用$ this来引用它们.
说我有以下课程....
class Foo {
private $pin;
private $stat;
public function get_stat($pin) {
$this->stat = shell_exec("blah read $pin");
return $this->stat;
}
}
Run Code Online (Sandbox Code Playgroud)
所以在上面的函数中,我将var $ pin传递给了class方法.这可以正常工作而不必使用$ this-> pin ...但是下面的代码看起来更像是正确的方法来做同样的事情.....
class Foo {
private $pin = 0;
private $stat = 0;
public function get_stat($pin) {
$this->pin = $pin;
$this->stat = shell_exec("blah read $this->pin");
return $this->stat;
}
}
Run Code Online (Sandbox Code Playgroud)
另外,我已经将$ pin和$ stat变量设置为= 0.我认为这可以是一个默认值,或者我可以像第一个示例私有$ pin一样定义它们.和私人$ stat;.
回到我的问题,关于如何在类方法中使用成员和$ this的最佳实践是什么?每个例子的优点和缺点是什么?
我正在使用Enterprise Architect制作UML类图并用它生成PHP5代码.使用它,可以为属性创建getter和setter,在代码中看起来像这样(只显示相关的行):
private $id;
public function getId()
{
return $this->id;
}
/**
*
* @param newVal
*/
public function setId($newVal)
{
$this->id = $newVal;
}
Run Code Online (Sandbox Code Playgroud)
我想使用魔术方法__get($property)而__set($property, $value)不是每个属性的单独方法.是否可能,如果可能,怎么样?
对于getter来说,它看起来像这样:
public function __get($property)
{
switch ($property) {
case 'id': return $this->id; break;
default: return null;
}
}
Run Code Online (Sandbox Code Playgroud) 考虑这个假设情景:
我有一个Stomach类,它有一个contents属性,Food应该为其分配类的对象.一种方法是使用一种设定器,例如setContents($food).
但我们假设我们直接分配食物,如$stomach->contents = $orange.
假设每当Food分配一个对象时,contents我们需要将对象的eaten属性更改为true.有没有办法在不使用被分配给它的对象的方法(在这种情况下,是它$stomach的setter)的情况下做到这一点?
基本上,我的问题是:每当一个对象被指定为另一个对象的属性时,我们可以调用一个方法吗?而且,即使有可能,设计也不好吗?对不起,如果这是一个愚蠢的问题,所有这些对我来说都是新鲜的.
我正在创建一个用户类来处理我的登录信息。因为我希望在验证用户名和密码后在类内设置会话,所以我是否必须在类顶部,要设置会话或实例的公共函数内使用session_start()创建的?也许可以放在函数_construct()中?
这就是我想给班级打电话的方式:
<php
include('user_class.php');
$user = new user;
$user->login($username,$password);
?>
Run Code Online (Sandbox Code Playgroud) 在最近的阅读中,我看到有关封装方法和OOP最佳实践的相互矛盾的建议.
我开始开发一系列PHP类,用于将数据从多个源系统传输和转换到最终目标.因此,第一个类的属性包含源URL和身份验证值.
对于具有无限扩展潜力的长期项目,以下哪项最佳?
声明为公共属性.在构造类时为每个源设置外部值.亲:简单.Con:没有封装优势
使用__get和__set.为每个源设置外部值.Pro:遵循OOP惯例.Con:打开所有外部访问; 再次,没有封装
将属性声明为受保护.对于我需要使用的每个源系统,扩展原始类并在子类中设置属性.Pro:带封装的OOP.Con:要管理的更多类和可能的文件.
目前,尽管存在文件开销,但选项3似乎是最好的.我也对其他想法持开放态度.
我读过这个问题的参考文献:
http://typicalprogrammer.com/?p=23
http://www.php.net/manual/en/language.oop5.overloading.php
我有很多关于它的帖子,但没有真正的答案:(.我的问题如下:
我有以下Bean类:
<?php
class ResultBean {
private $_label;
private $_resultSet;
private $_headerSet;
private $_numRows = 0;
private $_numFields = 0;
private $_empty = TRUE;
private $_dataArray;
private $_headerArray;
public function __construct($label) {
$v = trim($label);
$this->_label = empty($label) ? "" : $v;
}
public function setResultSet($value) {
if(!$value){
$this->_resultSet = null;
$this->_empty = TRUE;
}else{
$this->_resultSet = $value;
$this->_empty = FALSE;
}
return $this;
}
public function getResultSet() {
return $this->_resultSet;
}
public function getLabel() {
return $this->_label;
}
public …Run Code Online (Sandbox Code Playgroud)