워드 프레스 테마의 functions.php 파일에서 코드를 구성 하시겠습니까? 사용자 정의 기능이있는 경우 모든

WordPress에 대한 사용자 정의가 많을수록이 파일을 구성하거나 분할 해야하는지에 대해 더 많이 생각하기 시작합니다.

더 구체적으로, 관리 영역에만 적용되는 사용자 정의 기능과 공용 웹 사이트에만 적용되는 다른 사용자 정의 기능이있는 경우 모든 관리 기능을 자체 파일에 포함하거나 함께 그룹화 해야하는 이유가 있습니까?

파일을 별도의 파일로 나누거나 그룹화하면 WordPress 웹 사이트 속도가 빨라지거나 WordPress / PHP가 is_admin 코드 접두사가있는 기능을 자동으로 건너 뛰나요?

큰 함수 파일을 처리하는 가장 좋은 방법은 무엇입니까 (광산은 1370 줄입니다).



답변

테마의 코드 functions.php가 압도되기 시작 하는 시점에 도달하면 코드 를 여러 파일로 나눌 준비가 된 것입니다. 나는이 시점에서 거의 두 번째 본성으로하는 경향이 있습니다.

를 사용하여 테마의 포함 파일 functions.php파일

내 테마 디렉토리 아래에 “includes” 라는 서브 디렉토리를 작성 하고 당시의 말에 따라 구성되는 포함 파일로 코드를 세그먼트 화한다 (이는 사이트가 발전함에 따라 지속적으로 코드를 리팩터링하고 이동시키는 것을 의미한다). 실제 코드를 넣습니다 functions.php. 모든 것은 포함 파일에 들어갑니다. 단지 내 취향.

예를 들어 여기 WordPress Answers의 질문에 대한 답변을 테스트하는 데 사용하는 테스트 설치가 있습니다. 질문에 대답 할 때마다 다시 필요할 때를 대비하여 코드를 보관하십시오. 이것은 실제 사이트에서 수행 할 작업이 아니지만 코드를 나누는 메커니즘을 보여줍니다.

<?php 
/*
 * functions.php
 * 
 */
require_once( __DIR__ . '/includes/null-meta-compare.php');
require_once( __DIR__ . '/includes/older-examples.php');
require_once( __DIR__ . '/includes/wp-admin-menu-classes.php');
require_once( __DIR__ . '/includes/admin-menu-function-examples.php');

// WA: Adding a Taxonomy Filter to Admin List for a Custom Post Type?
// http://wordpress.stackexchange.com/questions/578/
require_once( __DIR__ . '/includes/cpt-filtering-in-admin.php'); 
require_once( __DIR__ . '/includes/category-fields.php');
require_once( __DIR__ . '/includes/post-list-shortcode.php');
require_once( __DIR__ . '/includes/car-type-urls.php');
require_once( __DIR__ . '/includes/buffer-all.php');
require_once( __DIR__ . '/includes/get-page-selector.php');

// http://wordpress.stackexchange.com/questions/907/
require_once( __DIR__ . '/includes/top-5-posts-per-category.php'); 

// http://wordpress.stackexchange.com/questions/951/
require_once( __DIR__ . '/includes/alternate-category-metabox.php');  

// http://lists.automattic.com/pipermail/wp-hackers/2010-August/034384.html
require_once( __DIR__ . '/includes/remove-status.php');  

// http://wordpress.stackexchange.com/questions/1027/removing-the-your-backup-folder-might-be-visible-to-the-public-message-generate
require_once( __DIR__ . '/includes/301-redirects.php');  

또는 플러그인 만들기

다른 옵션은 기능별로 코드를 그룹화하고 자신의 플러그인을 만드는 것입니다. 나를 위해 테마 functions.php파일 에서 코딩을 시작 하고 코드가 완성 될 때까지 대부분의 코드를 플러그인으로 옮겼습니다.

그러나 PHP 코드 구성으로부터 큰 성능 향상은 없습니다

반면에 PHP 파일을 구성하는 것은 순서 및 유지 관리 성을 만드는 데 99 %, 성능에 대해 1 %입니다 ( HTTP를 통해 브라우저에서 호출하는 조직 .js.css파일은 완전히 다른 경우이며 성능에 큰 영향을 미칩니다). 서버의 PHP 코드는 성능 측면에서 중요하지 않습니다.

그리고 코드 조직은 개인 취향입니다

마지막으로 코드 구성은 개인 취향입니다. 어떤 사람들은 코드를 구성하는 방식이 싫은 것처럼 코드를 구성하는 방식을 싫어합니다. 마음에 드는 것을 찾아서 고수하지만 시간이 지남에 따라 더 많이 배우고 더 편하게 전략을 발전시킬 수 있습니다.


답변

늦은 답변

올바른 방법으로 파일을 포함시키는 방법 :

function wpse1403_bootstrap()
{
    // Here we load from our includes directory
    // This considers parent and child themes as well    
    locate_template( array( 'inc/foo.class.php' ), true, true );
}
add_action( 'after_setup_theme', 'wpse1403_bootstrap' );

플러그인에서도 마찬가지입니다.

올바른 경로 또는 URi를 얻는 방법

또한 다음과 같은 파일 시스템 API 함수를 살펴보십시오.

  • home_url()
  • plugin_dir_url()
  • plugin_dir_path()
  • admin_url()
  • get_template_directory()
  • get_template_directory_uri()
  • get_stylesheet_directory()
  • get_stylesheet_directory_uri()
  • 기타

의 수를 줄이는 방법 include/require

디렉토리에서 모든 파일 을 가져와야 하는 경우

foreach ( glob( 'path/to/folder/*.php' ) as $file )
    include $file;

이는 실패 (프로덕션 사용에 적합) /로드 할 수없는 파일을 무시합니다.

이 동작을 변경하려면 개발 중에 다른 구성을 사용하려고 할 수 있습니다.

$files = ( defined( 'WP_DEBUG' ) AND WP_DEBUG )
    ? glob( 'path/to/folder/*.php', GLOB_ERR )
    : glob( 'path/to/folder/*.php' )

foreach ( $files as $file )
    include $file;

편집 : OOP / SPL 접근

방금 돌아와서이 답변이 점점 더 많은지지를 받고 있음을 보았을 때, 나는 PHP 5.3+ 세계에서 요즘 어떻게하고 있는지 보여줄 수 있다고 생각했습니다. 다음 예제는이라는 테마 하위 폴더에서 모든 파일을로드합니다 src/. 여기에는 메뉴, 이미지 등과 같은 특정 작업을 처리하는 라이브러리가 있습니다. 모든 단일 파일이로드 될 때 이름을 신경 쓰지 않아도됩니다. 이 디렉토리에 다른 하위 폴더가 있으면 무시됩니다.

\FilesystemIterator는 PHP 5.3+입니다 supercedor 오버 \DirectoryIterator. 둘 다 PHP SPL의 일부입니다. PHP 5.2에서는 내장 SPL 확장 기능을 끌 수 있었지만 (모든 설치 중 1 % 미만이 그랬습니다) SPL은 이제 PHP 핵심의 일부입니다.

<?php

namespace Theme;

$files = new \FilesystemIterator( __DIR__.'/src', \FilesystemIterator::SKIP_DOTS );
foreach ( $files as $file )
{
    /** @noinspection PhpIncludeInspection */
    ! $files->isDir() and include $files->getRealPath();
}

이전에는 여전히 PHP 5.2.x를 지원했지만 다음과 같은 솔루션을 사용 \FilterIterator했습니다. src/Filters디렉토리의 A 는 폴더의 점 포인터가 아닌 파일 만 검색하고 a \DirectoryIterator는 반복 및로드를 수행합니다.

namespace Theme;

use Theme\Filters\IncludesFilter;

$files = new IncludesFilter( new \DirectoryIterator( __DIR__.'/src' ) );
foreach ( $files as $file )
{
    include_once $files->current()->getRealPath();
}

\FilterIterator만큼 간단했다 :

<?php

namespace Theme\Filters;

class IncludesFilter extends \FilterIterator
{
    public function accept()
    {
        return
            ! $this->current()->isDot()
            and $this->current()->isFile()
            and $this->current()->isReadable();
    }
}

현재까지는 PHP 5.2가 죽고 / EOL이 아니라 (그리고 5.3도), 더 많은 코드와 게임에 파일이 하나 더 있다는 사실이 있기 때문에 나중에 나아갈 필요가 없으며 PHP 5.2.x를 지원할 이유가 없습니다.

요약

더 자세한 내용은 WPKrauts에서 확인할 수 있습니다 .

편집 분명히 올바른 방법은 네임 스페이스를 통해 이미 정의 된 적절한 디렉토리에 모든 것을 넣어 PSR-4 자동로드를 namespace위해 준비된 d 코드 를 사용 하는 것입니다. 그런 다음 Composer 와 a 를 사용하여 종속성을 관리하고 PHP 자동 로더를 자동으로 빌드하십시오 (이를 호출하여 파일을 자동으로 가져옵니다 ). WP Starter 는 PHP 세계에서 사실상의 표준이며, 가장 쉬운 방법이며 사전 자동화되고 단순화되었습니다 .composer.jsonuse \<namespace>\ClassName


답변

보일러 플레이트에서 사용자 정의 함수를 사용하여 테마 디렉토리에서 함수라는 폴더를 찾으십시오 (없는 경우). 그런 다음 해당 폴더에서 찾은 모든 .php 파일의 배열을 만들고 (있는 경우) include ()를 실행합니다. 그들 각각에.

이렇게하면 새로운 기능을 작성해야 할 때마다 함수 폴더에 PHP 파일을 추가하기 만하면 사이트에 코드를 코딩 할 필요가 없습니다.

<?php
/* 
FUNCTIONS for automatically including php documents from the functions folder.
*/
//if running on php4, make a scandir functions
if (!function_exists('scandir')) {
  function scandir($directory, $sorting_order = 0) {
    $dh = opendir($directory);
    while (false !== ($filename = readdir($dh))) {
      $files[] = $filename;
    }
    if ($sorting_order == 0) {
      sort($files);
    } else {
      rsort($files);
    }
    return ($files);
  }
}
/*
* this function returns the path to the funtions folder.
* If the folder does not exist, it creates it.
*/
function get_function_directory_extension($template_url = FALSE) {
  //get template url if not passed
  if (!$template_url)$template_url = get_bloginfo('template_directory');


  //replace slashes with dashes for explode
  $template_url_no_slash = str_replace('/', '.', $template_url);

  //create array from URL
  $template_url_array = explode('.', $template_url_no_slash);

  //--splice array

  //Calculate offset(we only need the last three levels)
  //We need to do this to get the proper directory, not the one passed by the server, as scandir doesn't work when aliases get involved.
  $offset = count($template_url_array) - 3;

  //splice array, only keeping back to the root WP install folder (where wp-config.php lives, where the front end runs from)
  $template_url_array = array_splice($template_url_array, $offset, 3);
  //put back togther as string
  $template_url_return_string = implode('/', $template_url_array);
  fb::log($template_url_return_string, 'Template'); //firephp

  //creates current working directory with template extention and functions directory    
  //if admin, change out of admin folder before storing working dir, then change back again.
  if (is_admin()) {
    $admin_directory = getcwd();
    chdir("..");
    $current_working_directory = getcwd();
    chdir($admin_directory);
  } else {
    $current_working_directory = getcwd();
  }
  fb::log($current_working_directory, 'Directory'); //firephp

  //alternate method is chdir method doesn't work on your server (some windows servers might not like it)
  //if (is_admin()) $current_working_directory = str_replace('/wp-admin','',$current_working_directory);

  $function_folder = $current_working_directory . '/' . $template_url_return_string . '/functions';


  if (!is_dir($function_folder)) mkdir($function_folder); //make folder, if it doesn't already exist (lazy, but useful....ish)
  //return path
  return $function_folder;

}

//removed array elements that do not have extension .php
function only_php_files($scan_dir_list = false) {
  if (!$scan_dir_list || !is_array($scan_dir_list)) return false; //if element not given, or not array, return out of function.
  foreach ($scan_dir_list as $key => $value) {
    if (!strpos($value, '.php')) {

      unset($scan_dir_list[$key]);
    }
  }
  return $scan_dir_list;
}
//runs the functions to create function folder, select it,
//scan it, filter only PHP docs then include them in functions

add_action('wp_head', fetch_php_docs_from_functions_folder(), 1);
function fetch_php_docs_from_functions_folder() {

  //get function directory
  $functions_dir = get_function_directory_extension();
  //scan directory, and strip non-php docs
  $all_php_docs = only_php_files(scandir($functions_dir));

  //include php docs
  if (is_array($all_php_docs)) {
    foreach ($all_php_docs as $include) {
      include($functions_dir . '/' . $include);
    }
  }

}

답변

폴더 안의 파일에 기능을 사용하고 싶습니다. 이 방법을 사용하면 새 파일을 추가 할 때 새로운 기능을 쉽게 추가 할 수 있습니다. 그러나 나는 항상 클래스 또는 네임 스페이스로 작성합니다-함수, 메소드 등의 네임 스페이스에 대해 더 많은 제어권을 부여하십시오.

작은 예 아래; 또한 클래스 * .php에 대한 계약과 함께 사용

public function __construct() {

    $this->load_classes();
}

/**
 * Returns array of features, also
 * Scans the plugins subfolder "/classes"
 *
 * @since   0.1
 * @return  void
 */
protected function load_classes() {

    // load all files with the pattern class-*.php from the directory classes
    foreach( glob( dirname( __FILE__ ) . '/classes/class-*.php' ) as $class )
        require_once $class;

}

테마에서 나는 종종 다른 시나리오를 사용합니다. 지원 ID에서 externel 파일의 기능을 정의합니다 (예 참조). externel 파일의 기능을 쉽게 비활성화 할 경우 유용합니다. WP 핵심 기능을 사용하고 require_if_theme_supports()지원 ID가 활성화 된 경우에만로드합니다. 다음 예에서는 파일을로드하기 전에 줄 에서이 지원되는 ID를 정의했습니다.

    /**
     * Add support for Theme Customizer
     * 
     * @since  09/06/2012
     */
    add_theme_support( 'documentation_customizer', array( 'all' ) );
    // Include the theme customizer for options of theme options, if theme supported
    require_if_theme_supports( 
        'documentation_customizer',
        get_template_directory() . '/inc/theme-customize.php'
    );

이 테마저장소 에서 더 많은 것을 볼 수 있습니다 .


답변

네트워크 설치를 통해 약 50 개의 고유 한 사용자 정의 페이지 유형이있는 서버를 다른 언어로 사이트를 관리합니다. 플러그인 톤과 함께.

우리는 어느 시점에서 그것을 모두 분할해야했습니다. 20-30k 줄의 코드가있는 함수 파일은 전혀 재미 있지 않습니다.

우리는 코드베이스를 더 잘 관리하기 위해 모든 코드를 리팩토링하기로 결정했습니다. 기본 워드 프레스 테마 구조는 작은 사이트에는 적합하지만 더 큰 사이트에는 적합하지 않습니다.

우리의 새로운 functions.php에는 사이트를 시작하는 데 필요한 것만 포함되어 있지만 특정 페이지에 속하는 것은 없습니다.

이제 우리가 사용하는 테마 레이아웃은 MCV 디자인 패턴과 비슷하지만 절차 적 코딩 스타일입니다.

예를 들어 회원 페이지 :

page-member.php . 페이지를 초기화합니다. 올바른 아약스 함수 또는 유사한 호출. MCV 스타일의 컨트롤러 부품과 동일 할 수 있습니다.

functions-member.php . 이 페이지와 관련된 모든 기능을 포함합니다. 이것은 회원을위한 기능이 필요한 다른 서버 페이지에도 포함되어 있습니다.

content-member.php . HTML에 대한 데이터를 MCV의 모델과 동등하게 준비합니다.

layout-member.php . HTML 부분.

Efter는 이러한 변경 작업을 수행하여 개발 시간이 50 % 쉽게 단축되었으며 이제 제품 소유자가 새로운 작업을 수행하는 데 어려움을 겪고 있습니다. 🙂


답변

자식 테마 functions.php 파일에서 :

    require_once( get_stylesheet_directory() . '/inc/custom.php' );

답변

functions.php에서 필요한 파일을 호출하는 더 우아한 방법은 다음과 같습니다.

require_once locate_template ( ‘/ inc / functions / shortcodes.php’);