Методы для кэширования PHP возражают против файла?

Что такое NullPointerException?

Хорошим местом для начала является JavaDocs . Они охватывают это:

Брошено, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  • Вызов метода экземпляра нулевого объекта.
  • Доступ или изменение поля нулевого объекта.
  • Выполнение длины null, как если бы это был массив.
  • Доступ или изменение слотов с нулевым значением, как если бы это был массив.
  • Бросать нуль, как если бы это было значение Throwable.

Приложения должны бросать экземпляры этого класса для указания других незаконных видов использования нулевого объекта.

blockquote>

Также, если вы попытаетесь использовать нулевую ссылку с synchronized, который также выдаст это исключение, за JLS :

SynchronizedStatement:
    synchronized ( Expression ) Block
  • В противном случае, если значение выражения равно null, NullPointerException.
blockquote>

Как это исправить?

Итак, у вас есть NullPointerException. Как вы это исправите? Возьмем простой пример, который выдает NullPointerException:

public class Printer {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer();
        printer.print();
    }
}

Идентифицирует нулевые значения

. Первый шаг - точно определить , значения которого вызывают исключение . Для этого нам нужно выполнить некоторую отладку. Важно научиться читать stacktrace . Это покажет вам, где было выбрано исключение:

Exception in thread "main" java.lang.NullPointerException
    at Printer.printString(Printer.java:13)
    at Printer.print(Printer.java:9)
    at Printer.main(Printer.java:19)

Здесь мы видим, что исключение выбрано в строке 13 (в методе printString). Посмотрите на строку и проверьте, какие значения равны нулю, добавив протоколирующие операторы или используя отладчик . Мы обнаруживаем, что s имеет значение null, а вызов метода length на него вызывает исключение. Мы видим, что программа перестает бросать исключение, когда s.length() удаляется из метода.

Трассировка, где эти значения взяты из

Затем проверьте, откуда это значение. Следуя вызовам метода, мы видим, что s передается с printString(name) в методе print(), а this.name - null.

Трассировка, где эти значения должны быть установлены

Где установлен this.name? В методе setName(String). С некоторой дополнительной отладкой мы видим, что этот метод вообще не вызывается. Если этот метод был вызван, обязательно проверьте порядок , что эти методы вызывают, а метод set не будет называться после методом печати. ​​

Этого достаточно, чтобы дать нам решение: добавить вызов printer.setName() перед вызовом printer.print().

Другие исправления

Переменная может иметь значение по умолчанию setName может помешать ему установить значение null):

private String name = "";

Либо метод print, либо printString может проверить значение null например:

printString((name == null) ? "" : name);

Или вы можете создать класс, чтобы name всегда имел ненулевое значение :

public class Printer {
    private final String name;

    public Printer(String name) {
        this.name = Objects.requireNonNull(name);
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer("123");
        printer.print();
    }
}

См. также:

Я все еще не могу найти проблему

Если вы попытались отладить проблему и до сих пор не имеете решения, вы можете отправить вопрос для получения дополнительной справки, но не забудьте включить то, что вы пробовали до сих пор. Как минимум, включите stacktrace в вопрос и отметьте важные номера строк в коде. Также попробуйте сначала упростить код (см. SSCCE ).

26
задан Matthieu Napoli 9 August 2013 в 08:59
поделиться

8 ответов

Сериализация является довольно безопасной и наиболее часто используемой. Однако существует альтернатива, и это должно кэшироваться к памяти. Выезд memcached и APC, они и свободны и очень производительны. Эта статья о различных методах кэширования в PHP могла бы также представлять интерес.

18
ответ дан Eran Galperin 28 November 2019 в 07:40
поделиться

Ре: Есть ли, другой сохраняет в файл метод, который я забываю?

Это имеет ограниченную утилиту, но если у Вас есть особенно раскормленный запрос базы данных, Вы могли бы записать сериализованный объект обратно к индексируемой таблице базы данных. У Вас все еще были бы издержки запроса базы данных, но это будет простой выбор в противоположность раскормленному запросу.

Ре: сохранение должно зарегистрировать безопасный? и дешевый общий хостинг-аккаунт)

печальный факт является дешевым общим хостингом, не безопасно. Насколько Вы доверяете этим 100,500 или 1 000 других людей, у которых есть доступ к Вашему серверу? Для исторического и (иронически) соображений безопасности, совместно использованные среды хостинга имеют PHP/Apache, работающий как непривилегированный пользователь (с PHP, работающим как модуль Apache). Безопасность, рациональная вот, - то, если мир, стоящий перед апачским процессом, поставился под угрозу, у эксплуататоров только есть доступ к непривилегированной учетной записи, которая не может завинтить с важными системными файлами.

плохая часть, который означает каждый раз, когда Вы пишете в файл с помощью PHP, владелец того файла является тем же непривилегированным пользователем Apache. Это верно для каждого пользователя в системе, что означает, что у любого есть доступ для чтения и доступ для записи к файлам. У теоретических хакеров в вышеупомянутом сценарии также был бы доступ к файлам.

существует также персистентная плохая практика в PHP предоставления каталога полномочий 777 к каталогам и файлам, чтобы позволить непривилегированному апачскому пользователю выписать файлы и затем отъезд каталога или файла в том состоянии. Это дает любой на системном доступе для чтения-записи.

Наконец, можно думать, что мрак сохраняет Вас. "Нет никакого способа, которым они могут знать, где мои секретные файлы кэша", но Вы были бы неправы. Общий хостинг настраивает пользователей в той же группе, и большинство масок файла по умолчанию даст Ваше разрешение чтения групповых пользователей на файлах, которые Вы создаете. SSH в Ваш общий хостинг-аккаунт когда-то, переместитесь по каталогу, и можно обычно начинать просматривать другие пользовательские файлы в системе. Это может использоваться для пронюхивания перезаписываемых файлов.

решения не симпатичны. Некоторые хосты предложат Обертку CGI, которая позволяет Вам выполнить PHP как CGI. Преимущество здесь является PHP, будет работать как владелец сценария, что означает, что это будет работать как Вы вместо непривилегированного пользователя. Проблема предотвращена! Новая проблема! Традиционный CGI является медленным как патока в феврале.

существует FastCGI, но FastCGI является привередливым и требует постоянной настройки. Не много общих хостов предлагают его. Если Вы находите тот, который делает, возможности, им включат APC и могут даже быть в состоянии обеспечить механизм для memcached.

7
ответ дан Alan Storm 28 November 2019 в 07:40
поделиться

То, что я всегда делаю, если я должен быть в состоянии записать, должно гарантировать, что я не пишу нигде, что у меня есть код PHP. Обычно моя структура каталогов выглядит примерно так (она варьировалась между проектами, но это - общее представление):

project/
  app/
  html/
    index.php
    data/
  cache/

app не перезаписываемо веб-сервером (ни один не index.php, предпочтительно). cache перезаписываемо и используется для кэширования вещей, таких как проанализированные шаблоны и объекты. data возможно перезаписываемо, в зависимости от потребности. Таким образом, если пользователи загружают данные, они входят в данные.

на веб-сервер указывают project/html и независимо от того, что метод удобен, используется для установки index.php как сценарий для выполнения за каждой страницей в проекте. Можно использовать mod_rewrite в Apache или согласование содержания (мое предпочтение, но часто не возможные), или безотносительно другого метода, который Вы любите.

Весь Ваш реальный код живет в app, который не непосредственно доступен веб-серверу, но должен быть добавлен к пути PHP.

Это работало вполне хорошо на меня для нескольких проектов. Я даже был в состоянии заставить, например, Викимедиа работать с измененной версией этой структуры.

, О... и я использовал бы, сериализируют ()/, не сериализируют (), чтобы сделать кэширование, хотя генерация кода PHP имеет определенное обращение. Все механизмы шаблонной обработки, о которых я знаю, генерируют код PHP для выполнения, делая постсинтаксический анализ очень быстро.

3
ответ дан Michael Johnson 28 November 2019 в 07:40
поделиться

Если у Вас есть доступ к Кэшу Запроса Базы данных (т.е. MySQL), Вы могли бы пойти с сериализацией Ваших объектов и хранением их в DB. База данных будет заботиться о содержании результатов запроса в памяти так, чтобы было довольно быстро.

1
ответ дан Jan Gorman 28 November 2019 в 07:40
поделиться

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

лучшее решение, учитывая зверские ограничения большей части недорогого общего хостинга, собирается зависеть от того, что Вы пытаетесь выполнить. Движение для нижней части общего хостинга барреля означает, что необходимо признать, что Вы не будете работать с лучшими инструментами. Чисел трудно определить количество, но существует компромисс между хостингом затрат, функционирование сайта & время разработчика (т.е. - быстрый, дешевый или легкий).

1
ответ дан Sean McSomething 28 November 2019 в 07:40
поделиться

Это находится в теории, возможной хранить объекты на сессиях. Это могло бы получить Вас мимо файла, пишущий отключенную проблему. Дополнительно Вы могли сохранить сессию в поддержанной таблице mysql памяти для ускорения запроса.

0
ответ дан Linor 28 November 2019 в 07:40
поделиться

Некоторым местам хостинга можно было скомпилировать APC в.. Это позволило бы Вам хранить объекты в памяти.

0
ответ дан DreamWerx 28 November 2019 в 07:40
поделиться

У меня была аналогичная проблема, и поэтому я написал решение - кэш памяти, написанный на PHP. Для поддержки сокетов требуется только сборка PHP. В остальном это чистое решение php, которое должно нормально работать на общем хостинге.

http://code.google.com/p/php-object-cache/

4
ответ дан 28 November 2019 в 07:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: