Я столкнулся с другой необходимостью создать новый набор определений для моей оболочки DOMDocument, упомянутой в этом посте. Я до сих пор не нашел каких-либо встроенных модулей для слияния элементов массива, но из-за природы этого конкретного приложения я действительно не хочу просто писать стандартные унаследованные свойства, потому что это может отчасти побороть цель написания оболочки вокруг DOMDocument на первом месте. (Если я в конечном итоге пойду по этому пути, я просто напишу что-нибудь, чтобы преобразовать свойства объекта PHP в элементы и атрибуты DOMDocument - что еще может произойти, если я найду способ легко создать defs из xsd автоматически)
Я забыл, что этот поток существует, но, по сути, в конечном итоге сделал то, что предлагали ответы, теперь, когда я несколько лучше справляюсь с областями в PHP, работая с ним. У новых определений, которые я создаю, есть ряд унаследованных (расширенных) типов в xsd для начала. Таким образом, определение определений в PHP для помощи в создании возможных элементов в DOMDocument, которые обертываются на нескольких уровнях в моделях, все равно требуется.
В абстрактный родительский базовый класс (тот, который на самом деле делает грязную работу по обертыванию DOMDocument и построению различных частей DOMElement sub-частей), я добавил следующую функцию:
public static function cascadeDefs($layer) {
if(!class_exists($layer)) {
$layerNS = __NAMESPACE__ . '\\DataTypes\\' . $layer;
if(class_exists($layerNS))
$layer = $layerNS;
}
if(class_exists($layer))
foreach($layer::$_elementDefs as $k => $v)
if(!isset(static::$_elementDefs[$k]))
static::$_elementDefs[$k] = $v;
}
Я подумал о том, чтобы иметь обратную трассировку, чтобы выяснить, что был вызывающий класс, а не передавать переменную $ layer, но нашел более полезным передать имя класса, так как это позволяет мне также «импортировать» определения из класс вне структуры наследования PHP.
Так, например, если у меня есть одно определение для типа customerPaymentProfileType, в котором имена базовых элементов (класс customerPaymentProfileBaseType) делятся с парой других вариантов платежных профилей. Затем существует другой тип, который имеет дополнительный параметр, но в остальном идентичен customerPaymentProfileType.
Одна из вещей, которые я делаю с этими определениями, заключается в том, что я назначаю «имя элемента», которое будет отображаться в окончательном xml-выводе элемента DOMElement, созданного в любой дочерней ветви конечного xml в главном конструкторе базы. абстрактный класс. Большинство «базовых» определений в XML эквивалентны абстрактному классу в PHP, и они не используются напрямую для определения типа элемента, а служат только как расширение для других типов. Однако customerPaymentProfile используется непосредственно как тип XML в одном определении.
У меня также есть проблема, заключающаяся в том, что при использовании определения типа Extended (Ex) имя элемента XML отличается, и обычно я передаю его имя на первом неабстрактном уровне.
Таким образом, вместо того, чтобы наследовать от простого типа, я могу наследовать от baseType (который расширяет основную обертку и включает определения базового элемента), добавить уникальный для расширенного определения, определить имя элемента [Different], а затем импортировать дополнительные параметры в базовой версии.
// technically extends customerPaymentProfileType but that is not an abstract and has different naming
class customerPaymentProfileExType extends customerPaymentProfileBaseType
{
//public static $_attrNames = array();
public static $_elementDefs = array(
'customerPaymentProfileId' => array(
'type' => 'string', // numeric string
'min' => 0
)
);
/**
* inherited child of the xmlAbstract::__construct to build a request XML data element
* @param null|array $elem
*/
public function __construct($elem=null) {
parent::__construct('paymentProfile',null,$elem);
self::cascadeDefs(get_parent_class(__CLASS__));
// add types from customerPaymentProfileType also
self::cascadeDefs('customerPaymentProfileType');
}
}
при нормальных обстоятельствах унаследованные элементы массива могут быть импортированы из родительского элемента с помощью всего лишь вызова:
self::cascadeDefs(get_parent_class(__CLASS__));