私はあなたが求めていることをするために少し前にこれを書きました。「compare_records」メソッドは、フィールド名でキー付けされた変更の連想配列を返します。各配列要素は、次の項目を持つ配列です。
- from: 元の (左) 値
- to: 新しい (右の) 値
- メッセージ: ログメッセージ
- イベント: 変更の性質を追加、削除、または変更として記述します
次のように呼び出します。
$changes = db_tools::compare_records( $array_old, $array_new );
class db_tools
{
public static $default_log_format = 'Field %1$s changed from "%2$s" to "%3$s"';
/**
* Returns a sorted list of keys from two arrays
**/
public static function get_keys( &$a, &$b )
{
$keys = array();
foreach( $a as $k => $v ) $keys[$k] = 1;
foreach( $b as $k => $v ) $keys[$k] = 1;
ksort( $keys );
return array_keys( $keys );
} // get_keys
/**
* Compares values in two arrays and returns array of differences.
*
* Each difference element is an associative array in the following format:
* 'field/key name' => array(
* 'from' => "from_val"
* , 'to' => "to_val"
* , 'message' => "Loggable message"
* , 'event' => "add" or "remove" or "change"
* )
*
* @param Array Original (old) array
* @param Array Comparison (new) array
* @param Array Special handling instructions -- allows you to ignore fields
* or truncate the logged value, as in:
* array(
* 'field_name' => 'ignore' // do not detect changes
* , 'field_2' => 0 // detect changes, but do not describe them
* , 'field_3' => 'from %2$s to %3s field %1$s was changed' // specially formatted log message
* );
* @param Array List of keys to compare. If this is omitted, the list will be
* constructed from keys in the first two arguments.
* @return Array
* @author J.D. Pace
* @since 2010/10/02
**/
public static function compare_records( &$a, &$b, $special = array(), $keyset = null )
{
$keys = ( empty( $keyset ) ? self::get_keys( $a, $b ) : $keyset );
$diff = array();
foreach( $keys as $k )
{
$_a = ( array_key_exists( $k, $a ) ? trim( $a[$k] ) : '' );
$_b = ( array_key_exists( $k, $b ) ? trim( $b[$k] ) : '' );
if( $_a != $_b )
{
$fmt = &self::$default_log_format;
if( array_key_exists( $k, $special ) )
{
if( $special[$k] == 'ignore' ) continue;
if( $special[$k] == '0' ) $fmt = '%1$s changed';
else $fmt = &$instr;
}
$diff[$k] = array(
'from' => $_a
, 'to' => $_b
, 'message' => sprintf( $fmt, $k, $_a, $_b )
, 'event' => (
empty( $_a )
? 'add'
: (
empty( $_b )
? 'remove'
: 'change'
)
)
);
}
}
return $diff;
}
/**
* Applies new data from record b to record a according to options keyset
* @param Array Destination Array
* @param Array Source Array
* @param Array Keys to apply. If this is omitted, record b will be copied
* into record a
**/
public static function update_record( &$a, &$b, $keyset = null )
{
$keys = ( empty( $keyset ) ? self::get_keys( $a, $b ) : $keyset );
$updated = array();
foreach( $keys as $k )
{
$a[$k] = ( empty( $b[$k] ) ? '' : $b[$k] );
}
}
} // class db_tools