草庐IT

php - 变量为空,直到重新分配

coder 2024-04-06 原文

我不太确定为什么会发生这种情况,或者如何正确解释它,但也许有人可以阐明这一点。

我有一个基于 CodeIgniter/Opencart 框架的 CMS 系统,它使用注册表、 Controller 和模块。我遇到了一个场景,我之前将一个变量保存到注册表中:

$this->application_page = 'current/page';

但由于某些原因,当我在应用程序中调用它时:

echo empty($this->application_page)?'yes':'no';
//Returns Yes

但是..当我重新分配它时:

echo empty($this->application_page)?'yes':'no';
//Returns Yes

$page = $this->application_page;
echo empty($page)?'yes':'no';
//Returns No

var_dump 返回:

var_dump($this->application_page);
string 'current/page' (length=12)

我可以通过使用 $page 轻松解决这个问题,但我很想知道为什么会这样?

更新:

所以我弄乱了 _isset 函数,但没有让它工作,可能是我的错误,也可能不是。这是它们如何协同工作的:

class Registry {
  private $data = array();
  public function get($key){ return (isset($this->data[$key]) ? $this->data[$key] : NULL); }
  public function set($key,$val){ $this->data[$key] = $val;
}

abstract class Controller {
  protected $registry;
  public function __construct($registry){ $this->registry = $registry; }
  public function __get($key){ return $this->registry->get($key); }
  public function __set($key,$value){ $this->registry->set($key, $value); }
}

class Applications {
  private $registry;
  function __construct($Registry){ $this->registry = $Registry; }
  function __get($key){ return $this->registry->get($key); }
  function __set($key,$val){ return $this->registry->set($key,$val); }
  public function buildApplication(){
      $this->application_page = 'current/page';
      $application = new application($this->registry);
  }

}

class Application extends Controller {
  public function index(){
    echo empty($this->application_page)?'yes':'no';
    //Returns Yes

    $page = $this->application_page;
    echo empty($page)?'yes':'no';
    //Returns No
  }
}

希望这有帮助? 有一个错字,Registry 的功能不是魔术方法。在应用程序中也声明了 $registry。

最佳答案

该类可能没有实现魔法 __isset()通过调用 isset() 触发的方法或 empty()关于不可访问的属性。


例子:

Live demo I :

<?php

class Test {
    private $a = '42';

    public function __get($name) {
        return $this->a;
    }
}

$obj = new Test();
var_dump($obj->a);        // string(2) "42"
var_dump(empty($obj->a)); // bool(true)

实现__isset()如下方法 ( Live demo II ) 将产生正确的结果:

public function __isset($name) {
    if ($name == 'a') {
        return true;
    }
    return false;
}

// ...
var_dump($obj->a);        // string(2) "42"
var_dump(empty($obj->a)); // bool(false)


这是实现 __isset() 的新代码版本方法:http://ideone.com/rJekJV

更改日志:

  • 向内部调用 Registry::has()Controller 类添加了 __isset() 方法。
  • Registy 类添加了 has() 方法。

  • [仅用于测试:对象初始化和运行 Application::index() 方法。]

有一个问题(更新您的答案后):

  • 您还没有将 $registry 声明为 Applications 类中的成员变量。
    否则代码会失败,因为它没有访问实际的成员变量(神奇的 __set() 方法!)

  • 此外,您的代码中有相当多的冗余(不是 DRY)。我希望这不是生产代码;)

关于php - 变量为空,直到重新分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18074005/

有关php - 变量为空,直到重新分配的更多相关文章

  1. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  2. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  3. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  4. Ruby Koans about_array_assignment - 非平行与平行分配歧视 - 2

    通过ruby​​koans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John

  5. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  6. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

    我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

  7. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  8. ruby - 匹配大写字母并用后续字母填充,直到一定的字符串长度 - 2

    我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种

  9. ruby - 在 Ruby 中重新分配常量时抛出异常? - 2

    我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案

  10. ruby-on-rails - 使用 ruby​​ 将多个实例变量转换为散列的更好方法? - 2

    我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。

随机推荐