워드프레스 Search workflow

limprove·2020년 8월 3일
0

워드프레스 Query

워드프레스는 한 화면을 로딩할 때, 여러개의 쿼리를 요청하여서 화면에 랜더링.

주로 wordpress loop가 동작할 때, 해당 쿼리의 결과를 loop가 돌면서 화면으로 랜더링한다.

자세히 설명하면, 워드프레스의 랜더링 방식은

  • 헤더              -> 워드프레스 루프() -> 쿼리 결과값을 랜더링
  • 사이드바       -> 워드프레스 루프() -> 쿼리 결과값을 랜더링
  • 컨텐츠(본문) -> 워드프레스 루프() -> 쿼리 결과값을 랜더링

이러한 방식으로 랜더링을 한다.

메인 쿼리는 사용자에 동작에 직접적으로 반응하는 쿼리
wordpress가 request URI에 표시 할 내용을 결정할 때, 자동으로 트리거 되는 쿼리.

사용자가 검색어를 입력하여, 검색 작업을 진행할 때,
url 형식은 [ /?s=검색키워드&post_type=product ]
http://martfurysearch.local/?s=phone&post_type=product

워드프레스는 이 url을 구문 분석(parsing)하여, 쿼리문을 작성한다.

wp-core에서 쿼리문를 작성하는 코드 흐름은

  1. wp-blog-header.php => wp( )
  2. functions.php => main( )
  3. class-wp.php => query_posts( )
  4. class-wp-query.php => query( )
  5. class-wp-query.php => get_posts( )
    1. 해당 파일 내 해당 함수 Ln1400 에서 쿼리 완성
    2. 쿼리의 키워드는 $wpdb -> posts의 값으로 가져오며
    3. 쿼리에 해쉬값은 prepare( )이 $placeholder 값을 키워드 앞뒤로 붙여줍니다. ( sql injection 대비/wp-db.php에서 해당 작업 처리 Ln2151 )

상단 2번에 main( ) 함수는 주요 로직을 실행
parse_request( )로 요청값을 구문 분석하여 쿼리에 필요한 변수 $query_vars를 세팅,
해당 함수 실행 후 query_posts( )함수가 실행하며, 바인딩 된 $query_vars의 정보를 활용하여 쿼리 생성

class-wp.php                 [WP]            -> 워드프레스 환경설정 클래스
class-wp-query.php     [WP_Query] -> 워드프레스 쿼리설정 클래스

%% 코드 리뷰 진행::디버깅 %%

검색창에 iphone 키워드 검색

  1. [core] index.php => define( 'WP_USE_THEMES')
    1. require ('wp-blog-header.php')
  2. [core] wp-blog-header.php => 3가지 큰 작업을 수행
    1. require('wp-load.php')
    2. wp()
    3. require('template-loader.php)
  3. [core] wp-load.php => [WP enviroment, ABSPATH 변경]
    1. require ('wp-config.php')
  4. [core] wp-config.php => [MySQL settings, Secret keys, Database table prefix, WP_DEBUG, ABSPATH]
  5. [core] wp-settings.php => 초기화에 필요한 파일들을 로드 (상수와 글로벌 변수, 플러그인, 버젼 정보 변수, 캐싱 정보, 코어 클래스 유틸), $wpdb 생성, mysql 연결, WP_Query 인스턴스 생성후 $GLOBALS['wp_the_query'] , $GLOBALS['wp_query']에 바인딩, WP 인스턴스 생성 후 $GLOBALS['wp']에 바인딩, 테마 설치, wp->init(), do_action('init')
    1. require('wp-settings.php')
    2. 여기서 해당 흐름은 종료 => 2-2 로직 실행
  6. [core] wp-blog-header.php => wp() 실행 [wp-settings.php 파일에서 functions.php를 로드하며 해당 파일에 정의 된 wp() 실행
  7. [core] functions.php => function wp()함수 정의부분
    1. wp>main(wp->main(query_vars) [class-wp.php 클래스 파일]
    2. public function main()는 6개의 함수를 실행 => 이중 query_posts()실행
    3. query_posts()는 생성된 $wp_the_query를 가지고 쿼리 스트링을 설정하고, query()함수를 실행 [여기서 쿼리스트링 설정하는 부분이 중요: bulid_query_string()]
    4. query()는 먼저 init()함수를 실행하고, wp_parse_args()된 결과값을 바인딩하여 get_posts()한다.
    5. get_posts()는 $wpdb(settings.php에서 생성)를 기반으로 쿼리문을 완성시킨다.

HASH코드는 sql injection 방지를 위해 붙는 해쉬값, esc_url(), $wpdb->prepare로 해쉬값을 붙일 수 있다.
메인 쿼리는 parse_search함수에 실행 결과를 $search변수에 담는데 prepare 메소드는 해당 쿼리에 %를 난독화한다.
add_placeholder_escape
마지막 로드함수 담겨있움 Ln2096참고

sql injection : https://noirstar.tistory.com/264

워드프레스 쿼리 변형

워드프레스 코어는 쿼리가 생성되고, 바인딩 되는 시점에 몇몇 hook 지점을 tag 해 놓았다.
해당 hook에 적합한 접근을 진행하면, 쿼리의 결과를 커스텀 할 수 있다.
클래스의 속성 중 WP_Query->query>query->query_vars 라는 변수가 있다.
쿼리 변수의 값을 가지고 있는 연관 배열이다. pre_get_posts 훅으로
$query->query_vars['name'] 혹은 $query->query_vars['meta_key']의 값을 바인딩하고, $query->query_vars['order']='ASC' 로 정렬에 관한 변수를 넣으면, 해당 쿼리는 변경이 된다.

하지만 해당 방식은 한계가 있는데, posts 되기 전 값을 변경하는 것이지, sql을 새로 생성하는 방식은 아니다. 제한적인 sql 수정이 가능한 방식이다,
또한 워드프레스의 meta 정보의 범위까지는 핸들링이 가능하나, 우커머스 테이블로 접근해야 하는 경우 작업이 어려워진다.

profile
즐겁게 개발하는 프론트엔드 개발자 입니다.

0개의 댓글