Как определить область действия переменной, чтобы она была доступна для других функций в том же CFC (плагин CFWheels)?

Я хочу добавить переменную, к которой могут обращаться все функции в плагине, но я получаю сообщение об ошибке «Неопределенная переменная». Вот мой плагин:

component
    mixin="Controller"
{
    public any function init() {
        this.version = "1.0";
        return this;
    }

    public void function rememberMe(string secretKey="rm_#application.applicationName#") {
        this.secretKey = arguments.secretKey;
    }

    public void function setCookie(required string identifier) {
        // Create a cookie with the identifier and encrypt it using this.secretKey
        // this.secretKey is not available, though, and an error is thrown
        writeDump(this.secretKey); abort;
    }
}

Я вызываю плагин из своего контроллера Sessions.cfc:

component
    extends="Controller"
{
    public void function init() {
        // Call the plugin and provide a secret key
        rememberMe("mySecretKey");
    }

    public void function remember() {
            // Call the plugin function that creates a cookie / I snipped some code
            setCookie(user.id);
        }
}
  1. Когда я выгружаю this.secretKey внутри плагина, я получаю переменную неопределенную ошибку. Ошибка говорит мне, что this.secretKey недоступен в контроллере Sessions.cfc. Но я не делаю дамп из Sessions.cfc, я делаю дамп из CFC плагина, как видите. Почему?

  2. Как я могу ограничить this.secretKey в своем плагине, чтобы к нему можно было получить доступ с помощью setCookie()? До сих пор variables и this терпели неудачу, добавляю ли я определения в функцию, псевдоконструктор или init(). На всякий случай я добавил variables.wheels.class.rememberME, но безрезультатно.

Вот ошибка:

Component [controllers.Sessions] has no acessible Member with name [secretKey]

person Mohamad    schedule 03.12.2011    source источник
comment
Пожалуйста, опубликуйте используемый вами CFML, который а) вызывает init() и б) вызывает Remember().   -  person Shawn Holmes    schedule 05.12.2011


Ответы (1)


То, что вы делаете в режиме init(), не будет работать в режиме production. init() контроллера запускается только при первом запросе для этого контроллера, потому что после этого он кэшируется.

Таким образом, this.secretKey будет установлено при самом первом запуске этого контроллера, но никогда при последующих запусках.

У вас есть несколько вариантов, чтобы сделать эту работу...

I. Используйте псевдоконструктор, который запускается при каждом запросе контроллера:

component
    extends="Controller"
{
    // This is run on every controller request
    rememberMe("mySecretKey");

    // No longer in `init()`
    public void function init() {}

    public void function remember() {
        // Call the plugin function that creates a cookie / I snipped some code
        setCookie(user.id);
    }
}

II. Используйте фильтр перед вызовом для каждого запроса:

component
    extends="Controller"
{
    // No longer in `init()`
    public void function init() {
        filters(through="$rememberMe");
    }

    public void function remember() {
        // Call the plugin function that creates a cookie / I snipped some code
        setCookie(user.id);
    }

    // This is run on every request
    private function $rememberMe() {
        rememberMe("mySecretKey");
    }
}

III. Сохраните ключ в постоянной области, чтобы вызов его только один раз из контроллера init() был в порядке.

component
    mixin="Controller"
{
    public any function init() {
        this.version = "1.0";
        return this;
    }

    public void function rememberMe(string secretKey="rm_#application.applicationName#") {
        application.secretKey = arguments.secretKey;
    }

    public void function setCookie(required string identifier) {
        // This should now work
        writeDump(var=application.secretKey, abort=true);
    }
}
person Chris Peters    schedule 05.12.2011
comment
Спасибо, это то, что я в итоге сделал. Затем я решил сдаться, потому что защита системы «запомнить меня» — это заноза в заднице, и это должно быть сделано с использованием дополнительного столбца db. Это делает его ужасным кандидатом на плагин. Итак, в конце концов, никакого плагина «запомнить меня» — позор, я понял это только после того, как закончил эту чертову штуку. Слово дня: Исследования! - person Mohamad; 05.12.2011