업데이트 : 내 원래 질문이 해결되었지만 전역 변수를 사용하지 않는 이유에 대한 유효한 토론으로 바뀌고 있으므로이를 반영하도록 질문을 업데이트하고 있습니다. 솔루션은 @TomJNowell이 제안한대로 <?php global $category_link_prop; echo esc_url( $category_link_prop ); ?>
였습니다.
업데이트 2 : 이제 내가 원하는대로 정확히 수행하고 있습니다. 하지만 저는 여전히 전역 범위를 사용하고 있으며 더 나은 방법을 찾게되어 기쁩니다.
저는 내 여러 위치에서 사용할 범주에 대한 영구 링크에 대한 전역 변수를 설정하려고합니다. 테마. 주된 이유는 현재 게시물이 어떤 카테고리에 속하는 지에 따라 선택된 일련의 하위 탐색뿐 아니라 기본 탐색에서 모두 사용하기 때문입니다. 이것은 테마가 아닙니다. 나는 다른 사람들이 사용하기 위해 릴리스 할 것이지만 매우 특정한 목적을 위해 만들어졌습니다.
이것은 내가 현재 그것들을 만드는 방법입니다 (몇 가지 변수 만 붙여 넣었습니다).
function set_global_nav_var() { //proposal global $prop; // Get the ID of a given category $category_id_prop = get_cat_ID( "proposal" ); // Get the URL of this category $category_link_prop = get_category_link( $category_id_prop ); $prop = "<a href="" .esc_url( $category_link_prop ). "" title="Proposal">Proposal</a>"; //Calvinball global $cb; // Get the ID of a given category $category_id_cb = get_cat_ID( "calvinball" ); // Get the URL of this category $category_link_cb = get_category_link( $category_id_cb ); $cb = "<a href="" .esc_url( $category_link_cb). "" title="Calvinball">Calvinball</a>"; } add_action( "init", "set_global_nav_var" );
이제 코드에 대한 전체 링크를 반환하는 4 곳에서 <?php global $prop; echo $prop; ?>
작업을 수행 할 수 있습니다. 변경 될 때 한 곳에서만 변경하면됩니다. 나는 전역 범위를 포함하지 않는 대안에 개방적입니다.
설명
- 이 문장은 어떤 링크를 사용합니까 echo esc_url ($ category_link_prop); ? 예상되는 링크는 무엇입니까?
- ‘ get_cat_ID (****) ‘ 전역 변수를 사용하려고 계획 한 곳입니다. 수행하는 방식만큼 속도 이점이있을 것 같지 않습니다. 가독성 관점에서 볼 때 ‘ get_cat_ID (****) ‘가 승리합니다.
- 다시 말할 수 있나요? 질문을 읽었는데 ‘ 아직도 잘 모르겠습니다. 하고 싶은 이유와 원하는 이유. 내 일반적인 조언은 전역 변수를 사용하지 않고 전역 범위를 오염시키지 않는 것입니다.
- 이것은 X / Y 문제 . 백업하고 원하는 결과가 무엇인지 정확히 설명해야합니다. I ‘ 확실합니다. 여기에 ‘ 여러 전역 변수를 설정 한 다음 다른 곳의 탐색에서 해당 변수에 대한 참조를 하드 코딩하는 것보다 훨씬 더 우아한 솔루션입니다.
- 메뉴를 출력하는 함수를 만듭니다. 전달한 컨텍스트에 따라 모든 메뉴 로직과 관련 변수를 한곳에 캡슐화 할 수 있습니다.
Answer
내가 이에 대해 강력히 권고하지만, 속도가 빨라지지는 지만 사용량은 올바르지 않습니다.
WordPress는 이미 이러한 항목을 개체 캐시에 캐시하므로 결과를 저장하고 재사용 할 필요가 없습니다. WP는 이미 수행합니다. .
이 마이크로 최적화의 결과로 코드가 더 느리게 실행되고있을 가능성이 큽니다.
글로벌 사용 방법
글로벌을 사용하려면 먼저 global
키워드를 지정해야합니다. 값을 정의 할 때 여기에 지정했지만 해당 범위 밖에서는 전역 범위 변수로 다시 선언해야합니다.
예 : functions.php
:
function test() { global $hello; $hello = "hello world"; } add_action( "after_setup_theme", "test" );
single.php
에서는 작동하지 않습니다.
echo $hello;
$hello
가 정의되지 않았기 때문입니다. 그러나 이것은 작동합니다 :
global $hello; echo $hello;
물론 둘 다해서는 안됩니다. WordPress는 이미 이러한 항목을 개체 캐시에 캐시하려고합니다 .
전역 변수의 단점 및 위험
이 작업을 수행해도 속도가 증가하지 않습니다 (약간의 속도 감소를 볼 수 있음). 얻을 수있는 것은 추가 복잡성과 필요하지 않은 많은 전역 선언을 입력해야하는 필요성뿐입니다.
또한 다른 문제가 발생합니다.
- 테스트를 작성할 수없는 코드
- 실행할 때마다 다르게 작동하는 코드
- 공유 네임 스페이스의 변수 이름 충돌
-
global
를 선언하는 것을 잊은 실수로 인한 버그 - 코드 데이터 저장소에 대한 구조
- 및 기타
대신 무엇을 사용해야합니까?
예를 들어 구조화 된 데이터를 사용하는 것이 좋습니다. 객체 또는 의존성 주입, 또는 귀하의 경우에는 함수 집합으로.
정적 변수
정적 변수 좋지는 않지만 글로벌 변수의 약간 덜 사촌이라고 생각하십시오.정적 변수는 전역 변수에 대한 것이고 진흙으로 덮인 빵은 청산가리에 대한 것입니다.
예를 들어, 여기에 정적 변수를 통해 유사한 작업을 수행하는 수단이 있습니다. 예 :
function awful_function( $new_hello="" ) { static $hello; if ( !empty( $new_hello ) ) { $hello = $new_hello; } return $hello; } awful_function( "telephone" ); echo awful_function(); // prints telephone awful_function( "banana"); echo awful_function(); // prints banana
싱글 톤
싱글 톤은 정적 변수와 유사하지만 클래스에 해당 클래스의 인스턴스가있는 정적 변수가 포함되어 있습니다. . 구문이 다르지만 전역 변수만큼이나 나쁩니다. 피하십시오.
WP_Cache, 시도했지만 WP는 이미 수행하고 있습니다.
정말 원하는 경우 재사용 할 데이터를 어딘가에 저장하여 시간을 절약하고 wp_cache_get
등과 함께 WP_Cache
시스템을 사용하는 것이 좋습니다.
$value = wp_cache_get( "hello" ); if ( false === $value ) { // not found, set the default value wp_cache_set( "hello", "world" ); }
이제 값은 WordPress의 요청 기간 동안 캐시되고 디버깅 도구에 표시됩니다. 객체 캐시가있는 경우 “요청간에 유지됩니다.
사이드 노트 1 : 일부 사람들은 요청에 걸쳐 전역 변수에 데이터를 유지하려고 시도하지만 이것이 PHP가 작동하는 방식이 아니라는 사실을 알지 못합니다. . 노드 애플리케이션과 달리 각 요청은 애플리케이션의 새 사본을로드 한 다음 요청이 완료되면 종료됩니다. 이러한 이유로 한 요청에 설정된 전역 변수는 다음 요청에 적용되지 않습니다.
참고 2 : 업데이트 된 질문으로 판단 할 때 전역 변수는 성능 향상을 전혀 제공하지 않습니다. 필요할 때 HTML을 생성하면됩니다. 그러면 HTML이 아주 조금 더 빠르게 실행될 것입니다. 이것은 마이크로 최적화입니다.
댓글
- 알고 있습니다 ‘ 전역 범위이지만 이러한 변수 중 일부는 모든 페이지에서 사용됩니다. 저는 ‘ 더 나은 아이디어에 열려 있습니다. 내 의도를 좀 더 명확하게하기 위해 질문을 편집하겠습니다. BTW 귀하의 제안에 따라
<?php global $category_link_prop; echo esc_url( $category_link_prop ); ?>
를 수행하면 완벽하게 작동합니다. 감사합니다! - 내 솔루션이 작동하면 수락 됨으로 표시 할 수 있나요? 전역 변수는 원래 호출을 수행하는 것만 큼 빠릅니다. 대신 함수를 사용해 볼 수 있으므로 ‘ 2 줄, 더 나은 방법은 싱글 톤을 입력 할 필요가 없습니다. 더 좋은 점은 모든 동적 및 get_template_part를 통해 포함 된 템플릿 부분에 포함하는 것입니다.
- @MarkKaplun이 아래에서 제안하는 전략 중 하나를 사용할 수 있지만 지금하고있는 작업으로 수락 된 것으로 표시됩니다. get_template_part ()를 사용하는 것은 흥미로운 아이디어이지만 ‘ 그런 짧은 파일로 가득 찬 디렉토리를 갖고 싶은지 모르겠습니다 …
- oooh no 아니요, ‘ 각 카테고리에 대한 파일을 원하지 않고 ‘ 현재 카테고리 이름을 잡고 사용하는 파일 만 원합니다. . ‘ 아무것도 하드 코딩 할 필요가 없습니다. 모든 하드 코딩의 번거 로움을 상상해보세요.
- 활성 상태 인 child-functions.php에 코드를 넣었습니다. 하지만 ” normal ” 데이터베이스 생성 게시물에서 호출하는 php-include 파일의 변수에 액세스 할 수 없습니다. 저에게 조언 해주세요. 제가 뭘 잘못 했나요? (물론 글로벌로 정의합니다.)
답변
전역 변수를 사용하지 마십시오 , 그렇게 간단합니다.
사용하지 않는 이유 글로벌 사용
글로벌을 사용하면 장기적으로 소프트웨어를 유지하기가 더 어려워지기 때문입니다.
- 글로벌 코드의 어느 곳에서나 선언 할 수 있습니다. 따라서 전역이 무엇에 사용되는지에 대한 주석을 찾기 위해 본능적으로 볼 수있는 곳이 없습니다.
- 코드를 읽는 동안 일반적으로 가정합니다. 변수는 함수에 국한되어 있으며 함수에서 값을 변경하면 시스템 전체가 변경 될 수 있음을 이해하지 못합니다.
- 입력을 처리하지 않으면 함수는 동일한 값 / 출력을 반환해야합니다. 동일한 매개 변수로 호출됩니다. 함수에서 전역을 사용하면 함수 선언에 문서화되지 않은 추가 매개 변수가 도입됩니다. .
- 전역에는 특정 초기화 구성이 없으므로 전역 값에 액세스 할 수있는시기를 확신 할 수 없으며 초기화 전에 전역에 액세스하려고 할 때 오류가 발생하지 않습니다. .
- 다른 사람 (플러그인)이 같은 이름의 전역을 사용하여 코드를 망칠 수 있으며 초기화 순서에 따라 망칠 수 있습니다.
WordPress 코어에는 글로벌을 많이 사용하는 방법입니다. the_content
와 같은 기본 기능이 작동하는 방식을 이해하려고하다가 갑자기 $more
변수가 로컬이 아니라 전역 변수이며 전체를 검색해야한다는 것을 깨달았습니다. true로 설정된 경우를 이해하기 위해 코어 파일의
그러면 첫 번째 실행 결과를 전역에 저장하는 대신 여러 줄의 코드 붙여 넣기를 중지하려고하면 & 어떻게 할 수 있습니까? 몇 가지 접근 방식, 기능 및 OOP가 있습니다.
감미료 기능. 단순히 복사 / 붙여 넣기를 저장하기위한 래퍼 / 매크로 일뿐입니다.
// input: $id - the category id // returns: the foo2 value of the category function notaglobal($id) { $a = foo1($id); $b = foo2($a); return $b; }
이제 장점은 이전 글로벌 작업에 대한 문서가 있다는 것입니다. 반환되는 값이 예상 한 값이 아닐 때 디버깅을위한 분명한 요점이 있습니다.
감미료가 있으면 필요한 경우 결과를 캐시하기 쉽습니다 (이 함수가 실행하는 데 오랜 시간이 걸립니다)
function notaglobal($id) { static $cache; if (!isset($cache)) { $a = foo1($id); $b = foo2($a); $cache = $b; } return $cache; }
이는 전역과 동일한 동작을 제공하지만 액세스 할 때마다 확실한 초기화를 수행 할 수 있다는 이점이 있습니다.
OOP와 유사한 패턴을 가질 수 있습니다. OOP는 보통 “플러그인과 테마에 어떤 가치도 추가하지 않지만, 이것은 다른 논의입니다.
class notaglobal { var latestfoo2; __constructor($id) { $a = foo1($id); $this->latestfoo2 = foo2($a) } } $v = new notaglobal($cat_id); echo $v->latestfoo2;
이것은 서투른 코드입니다. 항상 사용되기 때문에 미리 계산하고 싶은 값이 여러 개있는 경우이 방법을 사용할 수 있습니다. 기본적으로 이것은 조직화 된 방식으로 모든 전역을 포함하는 객체입니다.이 객체의 인스턴스를 전역으로 만들지 않으려면 (하나의 인스턴스를 원하고 그렇지 않으면 값을 다시 계산합니다) 싱글 톤 패턴 을 사용할 수 있습니다 (일부 사람들은 이것이 나쁜 생각이라고 주장합니다. YMMV)
객체 속성에 직접 액세스하는 것을 좋아하지 않으므로 내 코드에서 더 왜곡됩니다.
class notaglobal { var latestfoo2; __constructor() {} foo2($id) { if (!isset($this->latestfoo2)) { $a = foo1($id); $b = foo2($a); $this->latestfoo2= $b; } return $this->latestfoo2; } } $v = new notaglobal(); echo $v->foo2($cat_id);
댓글
- 제발, 소리 치지 마세요 ‘. 이유를 설명하고 인용을 해주시겠습니까?
- 답을 오해하신 것 같습니다. 전역 변수에 값을 저장하여 초기 최적화를 시도하지 않았다면 ‘ 그의 코드가 작동했을 것입니다. 기본적으로 확립 된 소프트웨어 개발 원칙을 따르는 것은 ‘ 충분히 강조 할 수 없기 때문입니다. 이러한 기본 원칙 (현지 Google에서 제공)을 이해하지 못하는 사람들은 인터넷을 통해 코드를 전파해서는 안됩니다.
- IMO 이것은 대답입니다. Google에서 여기에 온 사람들은 그것이 나쁜 생각이라는 것을 알아야합니다. 바로 글로벌 사용에 대해 생각할 수도 있습니다.
- ‘ X를하지 않는다고 말하기에는 충분하지 않습니다. 이유를 설명해야합니다. id = “348ef6a2e7”>
변덕스럽게 말하고 있습니다.
답변
귀하의 질문은 php가 작동하는 방식과 관련이 있습니다.
$ wpdb 를 예로 들면
$ wpdb 는 잘 알려진 전역 변수입니다.
언제 선언되고 값으로 할당되는지 아십니까?
로드되는 모든 페이지 , 그렇습니다. 워드 프레스 사이트를 방문 할 때마다
마찬가지로, 전역 화하려는 변수가 모든 페이지가로드 될 때마다 해당 값으로 선언되고 할당되는지 확인해야합니다.
테마 디자이너는 아니지만 after_setup_theme가 1이라고 말할 수 있습니다. 시간 후크. 테마가 활성화 된 경우에만 트리거됩니다.
내가 당신이라면 init 또는 다른 후크를 사용합니다. 아니요, 제가 당신이라면 전역 변수를 전혀 사용하지 않을 것입니다 …
나는 정말로 설명을 잘 못합니다. 따라서 PHP에 대해 자세히 알아 보려면 책을 선택해야합니다.
답변
언제든지 싱글 톤 패턴을 사용할 수 있습니다. 정적 게터를 통해.
<ul> <li><?php echo MyGlobals::get_nav_prop( "proposal" )[ "html" ]; ?></li> <li><?php echo MyGlobals::get_nav_prop( "calvinball", "html" ); ?></li> </ul> <?php if ( ! class_exists("MyGlobals") ): class MyGlobals { public $props; public function __construct(){ $this->props = array ( "proposal" => array( "title" => "Proposal", "text" => "Proposal" ), "calvinball" => array( "title" => "Calvinball", "text" => "Calvinball" ), ); } public function get_nav_prop ( $term, $prop = false ) { $o = self::instance(); if ( ! isset( $o->props[$term] ) ) { return falst; } if ( ! isset( $o->props[$term][ "html" ] ) ) { $id = get_cat_ID( $term ); $link = esc_url ( get_category_link( $id ) ); $title = $o->props[$term]["title"]; $text = $o->props[$term]["text"]; $o->props[$term]["html"] = "<a href="".$link."" title="".$title."">".$text."</a>"; $o->props[$term]["link"] = $link; $o->props[$term]["id"] = $id; } if($prop){ return isset($o->props[$term][$prop]) ? $o->props[$term][$prop] : null; } return $o->props[$term]; } // ------------------------------------- private static $_instance; public static function instance(){ if(!isset(self::$_instance)) { self::$_instance = new MyGlobals(); } return self::$_instance; } } endif; // end MyGlobals