데이터베이스를 수정하는 WordPress 플러그인 업데이트를 구현하는 방법은 무엇입니까?


10

여러 데이터베이스 테이블이있는 WordPress 플러그인을 개발합니다. 플러그인은 활성화 될 때 이러한 테이블을 작성하고 삭제 / 제거시 제거합니다.

플러그인의 코드와 테이블 구조를 업데이트하는 플러그인의 업데이트 프로세스를 구현해야합니다. 가장 간단한 경우는 테이블 중 하나에 새 열을 추가하는 것입니다. 더 복잡한 경우는 새 테이블 구조를 작성하고 그에 따라 컨텐츠를 업데이트하는 것입니다.

이 문제를 어떻게 해결 하시겠습니까? 도움이 될 수있는 기본 제공 WordPress 기능이 있습니까?

답변:


4

요즘 올바른 방법은 스키마를 플러그인 소스에 파일로 포함하고 내장 된 WordPress 함수 dbDelta ()를 사용하여 해당 스키마를 사용하여 필요에 따라 데이터베이스를 업데이트하는 것입니다. 필요한 실제 코드는 매우 간단합니다.

$sql = file_get_contents( plugin_dir_path(__FILE__) . "/schema.sql" );
dbDelta( $sql );

필요에 따라 데이터베이스를 작성하고 업데이트합니다. 내가 마지막으로 확인했을 때 오래된 사용하지 않는 열을 삭제하지 않았으므로 버전 확인을 통해 해당 열을 코딩해야합니다. 이것은 WordPress의 아름다운 기능이며 엄청난 시간 절약 기능입니다. dbDelta () 코드가 간격에 대해 매우 까다로운 것으로 판명되는 것처럼 mysql 스키마 내보내기에서 간격을 복사하는 schema.sql 파일을 작성할 때주의하십시오. 또한 데이터베이스 버전을 테스트해야하며 최신 버전이 아닌 경우 위의 전화를 걸어 데이터베이스를 업데이트하십시오. dbDelta ()가 올바르지 않은 변경 사항 (예 : 열 삭제)을 처리하기 위해 특정 업데이트를 수행해야 할 수도 있습니다. 버전이 업데이트되었는지 확인하고 $ wpdb를 통해 이러한 수동 업데이트를 수행하는 경우 간단한 논리 if 테스트를 작성하는 것이 쉽습니다. 예를 들어, 사용하지 않는 열을 삭제할 수 있습니다.

$installed_ver = get_option(MY_DB_VERSION);
$wpp = $wpdb->prefix . "mypluginname";
if ($installed_ver < 102)
        $wpdb->query("ALTER TABLE ${wpp}_movies DROP nft_date");
if ($installed_ver < 107)
        $wpdb->query("ALTER TABLE ${wpp}_movies CHANGE lastupdated "
        . "lastupdated TIMESTAMP on update CURRENT_TIMESTAMP "
        . "NOT NULL DEFAULT CURRENT_TIMESTAMP");

update_option(MY_DB_VERSION, $db_version);

코드 실행 과정에서 단순화되었습니다. 게시를 위해 코드를 단순화하는 과정에서 코드를 깨뜨린 경우 사과드립니다.

또한 WordPress 3.9.2부터 WordPress는 플러그인 업데이트시 (특히 대시 보드 업데이트 페이지에서 대량 업데이트를 수행하는 경우) 항상 활성화 후크를 실행하지는 않습니다.


요즘에는 schema.sql 파일의 모드 시간에서 DB 버전을 가져 오기 시작했습니다. 이는 scheme.sql 파일 만 업데이트하면 데이터베이스를 업그레이드하기에 충분하다는 것을 의미합니다. 데이터베이스 버전을 편집 할 필요가 없습니다. $ db_version = filemtime (“schema.sql”);
Brian C

1
따라서 파일 시간이 서버 이동과 같은 외부에서 변경되면 mtime과 db 버전이 변경됩니까?
Walf November

파일 시간은 항상 GMT이며 서버는 몇 초 정도 차이가 거의 없으므로 두 번 트리거되는 것은 거의 불가능합니다. 그러나 다시 트리거 되더라도 한 번 실행해도 아무런 영향을 미치지 않으며 변경 사항없이 라이브 DB와 비교합니다. 이것은 dbDelta ()의 아름다운 점입니다. 문제없이 여러 번 실행될 수 있습니다. 좋은 질문입니다. 감사합니다.
Brian C

3

요컨대- $wpdb클래스입니다. 자세한 내용은 코덱 을 참조하십시오.

사용자 정의 테이블 (또는 실제로는 모든 테이블)과 상호 작용할 때마다 $wpdb특히 prepare쿼리를 피하고 주입을 방지하는 데 도움 이되는 방법에 익숙해야합니다 .

테이블을 작성하는 데 사용해야하므로 이미 익숙해야합니다. 설치 후크에는 다음과 같은 것이 있어야합니다.

$charset_collate = '';
if ( ! empty($wpdb->charset) )
    $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
if ( ! empty($wpdb->collate) )
    $charset_collate .= " COLLATE $wpdb->collate";

//Create custom table
$sql_custom_table ="CREATE TABLE {$wpdb->prefix}my_table (
    id bigint(20) unsigned NOT NULL auto_increment,
    column_a varchar(255) default NULL,
    column_b varchar(255) default NULL,
    PRIMARY KEY  (id)
    ) $charset_collate; ";

require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql_custom_table);

이 코드는 실제로 플러그인이 활성화 될 때마다 (즉, 설치되지 않은 경우에만) 실행됩니다. 따라서 누군가가 플러그인을 자동으로 업데이트 할 때 실행 됩니다 . 참고 : 플러그인을 수동으로 교체하여 업그레이드하는 경우 그렇지 않습니다. 따라서 admin_init플러그인을 업그레이드 할 때 위의 코드를 트리거해야합니다 (옵션 테이블에 버전 번호 저장, 현재 버전 확인) .

이제는 CREATE TABLE플러그인을 업데이트 할 때마다 일반적으로 SQL 명령이 실행되는 것을 원하지 않습니다 dBDelta().

위의 명령을 실행하기 전에-테이블이 존재하는지 확인합니다. 또한 열 유형을 확인합니다. 따라서 테이블이 존재하지 않으면 테이블을 생성하고 존재하는 경우 테이블을 생성하지만 일부 컬럼 유형이 테이블을 변경하고 컬럼이 존재하지 않는 경우 테이블을 추가합니다.

불행히도-위의 열을 제거하면 열이 자동으로 제거되지 않습니다. 열 / 테이블을 제거하려면 구체적으로 열 / 테이블을 제거해야 DROP합니다 (확인하기 전에 존재하는지 확인).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.