Должны ли мы доверять почтовым глобалам?

21

@toscho оставил комментарий к этому ответу, который заставил меня задуматься. Насколько мы должны доверять глобальному охвату, особенно в отношении почтовых глобалов, таких как $post?

Ну и что? Глобальная переменная может быть перезаписана всеми перед выполнением проверки. В этом суть глобальных переменных: глобальный доступ.

$postнапример, это, безусловно, один из глобалов, который в основном изменяется либо в самой теме, либо с помощью плагинов. Тем не менее, он также является глобальным, наиболее часто используемым в других приложениях в данном шаблоне, например, для настройки связанных постов.

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

Из этого видно, что $postэто не надежно. Любой плохо написанный фрагмент кода, который использует пользовательский запрос, может изменить $postглобальный, что, в свою очередь, что-то сломает (например, связанные посты).

Лишь немногие разработчики WordPress достаточно хорошо разбираются во внутренней работе ядра и знают, чего следует избегать, а что нет. Большая часть пользователей понятия не имеет, как работает ядро ​​WordPress.

Они просто загружают тему и устанавливают плагины, чтобы делать то, что нужно, или даже просто копируют код из учебника. Скажем, они устанавливают плохо написанный плагин, который ломает связанные с ними посты в одном посте, как они узнают, что вызвало это? Удастся ли им разобраться с этим самостоятельно, или это будет сотый человек, который напишет электронное письмо автору темы об этой проблеме или разместит вопрос на этом сайте?

Мой вопрос: как вы можете защитить себя от таких проблем, вызванных другим импортированным кодом, когда глобальное подобное $postнастолько ненадежно? Должны ли мы использовать глобальный, как $postна всех? Какие есть альтернативы?

Просто чтобы поделиться своим мнением здесь, прежде чем я сделаю вывод: я подумал (и видел в некоторых темах и плагинах тоже) , что нужно использовать wp_reset_postdata()или wp_reset_query()перед использованием $post, чтобы убедиться, что глобальный объект сбрасывается на главный запрос $post. Но почему я должен раздувать свой код в моей теме, потому что кто-то еще не правильно кодировал его плагин? И если кто-то правильно сбросил свой пользовательский запрос, эта операция запускается ненужный второй раз, что не очень хорошо.

Второй метод, о котором я подумал, - это использовать, $wp_queryа затем использовать его методы, что-то вроде $wp_query->post.

Любые мысли по этому поводу будут оценены.

Питер Гусен
источник
Сброс поста просто копирует переменную в другую, вы могли бы назвать это миллион раз в своем коде и не увидеть снижения производительности, поэтому я не знаю, что в этом плохого.
Майло

Ответы:

16

Есть печальная истина: вы никогда не можете быть уверены, что какой-то код не нарушит ваш код, и вы ничего не можете сделать, чтобы предотвратить это. Особенно в WordPress, где все глобально.

Тем не менее, да, global $postявляется одним из наиболее часто используемых глобальных var, поэтому использование специальной заботы о нем может быть хорошей идеей.

В моем коде я редко напрямую обращаюсь к глобальным $post.

Находясь в единственном числе , я использую get_queried_object()и обычно проверяю, $postявляется ли действительный WP_Postэкземпляр:

$post = get_queried_object();

if ( ! $post instanceof \WP_Post ) {
   die( 'What the f**k?!' );
}

Я делаю эту проверку и в тех редких случаях, к которым у меня есть $postпрямой доступ .

Учтите, что это get_queried_object()возвращает неожиданное значение, если какой-то код использует query_posts, но, эй, если кто-то использует код, на который он опирается query_posts, он этого заслуживает, если его сайт ломается :)

Более того, если я ожидаю каких-то условий, я проверяю их, например, конкретные типы сообщений или определенный статус.

Если мне нужно больше проверок и в большем количестве мест, я создаю функцию для их выполнения:

function get_global_post() {
    global $post;
    if ( 
        ! $post instanceof \WP_Post
        || ! $post->post_type === 'mycpt'
        || ! in_array( $post->post_status, array( 'publish', 'private' ), true ) 
    ) {
        return false;
    }
    return $post;
}

$mypost = get_global_post();

if ( ! $mypost ) {
      die( 'What the f**k?!' );
}

Когда внутри пользовательского запроса, во время цикла, вызов the_post()сбрасывает объект post, так что все должно быть в порядке. Тогда я отвечаю за вызов wp_reset_postdata()после пользовательского запроса, и я делаю это, конечно :)

Gmazzap
источник