Ограничение доступа к переменным - PullRequest
3 голосов
/ 14 сентября 2010

Мне нужна переменная, которую может написать только одна функция (давайте назовем эту функцию a) и что может прочитать только одна другая функция (давайте вызовем эту функцию b).Это возможно?

Ответы [ 4 ]

6 голосов
/ 14 сентября 2010

Вы можете использовать статическую переменную :

function foo($val=null) {
    static $var = null;
    if (!is_null($var)) $var = $val;
    return $val;
}

Здесь $var отображается только внутри функции foo и поддерживается в течение нескольких вызовов:

foo(123);
echo foo();  // 123
foo(456);
echo foo();  // 456

Или используйте класс с закрытым членом и получите доступ / измените его с помощью открытых методов:

class A {
    private $var;
    public function setVar($val) {
        $this->var = $val;
    }
    public function getVar() {
        return $this->var;
    }
}

При этом закрытый член var виден только определенному экземпляру этого класса:

$obj1 = new A();
$obj1->setVar(123);
$obj2 = new A();
$obj2->setVar(456);
echo $obj1->getVar();  // 123
echo $obj2->getVar();  // 456

Если вы сделаете член статическим , тогда для класса будет только один элемент вместо каждого:

class A {
    private static $var;
    public function setVar($val) {
        self::$var = $val;
    }
    public function getVar() {
        return self::$var;
    }
}
$obj1 = new A();
$obj1->setVar(123);
$obj2 = new A();
$obj2->setVar(456);
echo $obj1->getVar();  // 456
echo $obj2->getVar();  // 456
1 голос
/ 14 сентября 2010

Вы имеете в виду функции друга ?Потому что я хотел бы быть в состоянии сделать это.Пока что я не нашел простой способ (хотя вы могли бы попробовать использовать Reflection, но это похоже на способ больших усилий).

Для меня это обычно не проблема сохранения целостности / инкапсуляции данных, а сохранения списка открытых методов (что-то вроде API класса) без помех.Идеальная структура должна быть простой в использовании, иметь очевидные имена функций и т. Д. И т. Д. И т. Д. Методы, предназначенные для использования одним другим методом, действительно запутывают.«Решение», к которому я пришел, - это префикс этих имен функций одним или двумя подчеркиваниями и запись «предназначенные только для внутреннего использования» или что-то подобное в комментариях.

1 голос
/ 14 сентября 2010

Начиная с версии 5.3.0, вы можете использовать анонимные функции в качестве замыканий . Преимущество здесь в том, что вы можете удерживать b ..., который возвращается a ... и запускать его, когда будете готовы:

<?php
function a()
{
    // Only a() can write to $myVar
    $myVar = 42;
    $b = function() use ($myVar)
    {
        // $b can read $myVar
        // no one else can
        return $myVar;      
    };
    return $b;
}

  // get $b
$test = a();
  // use $b
echo $test();
?>

Другое решение до 5.3.0, но здесь a должно запустить b, что может быть не так практично:

Вы можете просто создать внутреннюю переменную и передать ее в качестве аргумента. Вы можете сделать это внутри класса или просто внутри простых функций:

function a()
{
    // ...
    // Write the variable that
    // only this function can write to
    $thisVar = 1;
    b($thisVar);
    //...
}

function b($myVar)
{
    // ...
    // Do stuff w $myVar, a copy of $thisVar
    // Changing $myVar has no effect on $thisVar
    //
}
1 голос
/ 14 сентября 2010

Вы можете использовать статический абстрактный класс.

abstract class Settings
{
    private static var $_settings = array();

    public static function get($key,$default = false)
    {
        return isset(self::$_settings[$key]) ? self::$_settings[$key] : $default;
    }

    public static function set($key,$value)
    {
        self::$_settings[$key] = $value;
    }
}

Пример использования:

Settings::set('SiteName',`SomeResult`);

echo Settings::get('SiteName');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...