Tôi khá mới với PHP, DOM và triển khai PHP DOM. Những gì tôi đang cố gắng thực hiện là lưu phần tử gốc của số DOMDocument
vào biến số $_SESSION
để tôi có thể truy cập và sửa đổi thành phần tải trang tiếp theo.
Nhưng tôi nhận được một lỗi trong PHP khi sử dụng $_SESSION
để lưu trạng thái của DOMElement:
Cảnh báo: DOMNode :: appendChild() [domnode.appendchild]: Không thể lấy DOMElement
Tôi đã đọc rằng một đối tượng DOMDocument PHP không thể được lưu vào $_SESSION
nguyên bản. Tuy nhiên, nó có thể được lưu bằng cách lưu tuần tự hóa của DOMDocument (ví dụ: $_SESSION['dom'] = $dom->saveXML()
).
Tôi không biết điều tương tự có đúng với việc lưu một số DOMElement
thành một biến số $_SESSION
hay không, nhưng đó là những gì tôi đang cố gắng. Lý do tôi muốn làm điều này là sử dụng một lớp DOMElement mở rộng với một thuộc tính bổ sung. Tôi đã hy vọng rằng bằng cách lưu DOMElement gốc trong $ _SESSION mà sau này tôi có thể lấy phần tử và sửa đổi thuộc tính bổ sung này và thực hiện một phép thử như, nếu (addProperty === false) {làm điều gì đó; }. Tôi cũng đã đọc điều đó bằng cách lưu một DOMDocument và sau đó lấy nó, tất cả các phần tử được trả về như các đối tượng từ các lớp DOM nguyên gốc. Tức là, ngay cả khi tôi đã sử dụng một lớp mở rộng để tạo ra các phần tử, thì thuộc tính mà tôi sau đó cần sẽ không thể truy cập được, vì biến giữ tham chiếu đến đối tượng lớp mở rộng đã vượt quá phạm vi - đó là lý do tại sao tôi ' m cố gắng điều này khác. Tôi đã thử sử dụng lớp mở rộng (không bao gồm bên dưới) trước, nhưng có lỗi ... vì vậy tôi đã hoàn nguyên về việc sử dụng đối tượng DOMElement để xem đó có phải là sự cố hay không, nhưng tôi vẫn gặp lỗi tương tự. Dưới đây là các mã:
<?php
session_start();
$rootTag = 'root';
$doc = new DOMDocument;
if (!isset($_SESSION[$rootTag])) {
$_SESSION[$rootTag] = new DOMElement($rootTag);
}
$root = $doc->appendChild($_SESSION[$rootTag]);
//$root = $doc->appendChild($doc->importNode($_SESSION[$rootTag], true));
$child = new DOMElement('child_element');
$n = $root->appendChild($child);
$ct = 0;
foreach ($root->childNodes as $ch) echo '<br/>'.$ch->tagName.' '.++$ct;
$_SESSION[$rootTag] = $doc->documentElement;
?>
Mã này mang đến cho các lỗi sau đây (tuỳ thuộc vào việc tôi sử dụng appendChild trực tiếp hoặc dòng nhận xét của mã sử dụng importNode):
Warning: DOMNode::appendChild() [domnode.appendchild]: Couldn't fetch DOMElement in C:\Program Files\wamp_server_2.2\www\test2.php on line 11
Warning: DOMDocument::importNode() [domdocument.importnode]: Couldn't fetch DOMElement in C:\Program Files\wamp_server_2.2\www\test2.php on line 12
tôi có một số câu hỏi. Trước tiên, điều gì gây ra lỗi này và cách khắc phục sự cố? Ngoài ra, nếu những gì tôi đang cố gắng làm là không thể, sau đó làm thế nào tôi có thể thực hiện mục tiêu chung của tôi về tiết kiệm 'nhà nước' của một cây DOM trong khi sử dụng một thuộc tính tùy chỉnh cho mỗi phần tử? Lưu ý rằng thuộc tính bổ sung chỉ được sử dụng trong chương trình và không phải là thuộc tính được lưu trong tệp XML. Ngoài ra, tôi không thể chỉ lưu DOM trở lại tệp mỗi lần, vì DOMDocument, sau khi sửa đổi, có thể không hợp lệ theo lược đồ tôi đang sử dụng cho đến sau khi bổ sung modificaitons/bổ sung đã được thực hiện cho DOMDocument. Đó là lý do tại sao tôi cần phải lưu một DOMDocument tạm thời không hợp lệ. Cảm ơn lời khuyên nào!
CHỈNH SỬA: Sau khi thử giải pháp của hakre, mã đã hoạt động. Sau đó, tôi chuyển sang sử dụng một lớp DOMElement mở rộng, và, như tôi nghi ngờ, nó không hoạt động. Đây là mã mới:
<?php
session_start();
//$_SESSION = array();
$rootTag = 'root';
$doc = new DOMDocument;
if (!isset($_SESSION[$rootTag])) {
$root = new FreezableDOMElement($rootTag);
$doc->appendChild($root);
} else {
$doc->loadXML($_SESSION[$rootTag]);
$root = $doc->documentElement;
}
$child = new FreezableDOMElement('child_element');
$n = $root->appendChild($child);
$ct = 0;
foreach ($root->childNodes as $ch) {
$frozen = $ch->frozen ? 'is frozen' : 'is not frozen';
echo '<br/>'.$ch->tagName.' '.++$ct.': '.$frozen;
//echo '<br/>'.$ch->tagName.' '.++$ct;
}
$_SESSION[$rootTag] = $doc->saveXML();
/**********************************************************************************
* FreezableDOMElement class
*********************************************************************************/
class FreezableDOMElement extends DOMElement {
public $frozen; // boolean value
public function __construct($name) {
parent::__construct($name);
$this->frozen = false;
}
}
?>
Nó cho tôi lỗi Undefined property: DOMElement::$frozen
. Như tôi đã đề cập trong bài đăng gốc của mình, sau saveXML
và loadXML
, một phần tử được khởi tạo ngay lập tức với FreezableDOMElement
đang trả về loại DOMElement
đó là lý do tại sao thuộc tính frozen
không được nhận dạng. Có cách nào để khắc phục điều này?
Cảm ơn bạn đã phản hồi nhanh. Tôi sẽ cố gắng thực hiện giải pháp mà bạn mô tả. Tuy nhiên, có vẻ như tôi có thể sẽ vẫn gặp sự cố không có các thuộc tính lớp mở rộng có thể truy cập khi chuỗi XML được tải lại vào DOMDocument, đúng không? – neizan
@neizan: Về những gì bạn nói ở đây? Nếu bạn chăm sóc serialization của riêng bạn, bạn nên có tất cả các khả năng bạn đang tìm kiếm. Nó chỉ là thường xuyên tuần tự hóa 'DOMDocument' làm cho không có ý nghĩa, như XML là một hình thức serialization đã. – hakre
Phải, khi tôi nói serialization tôi đã đề cập đến bằng cách sử dụng phương pháp 'saveXML', xin lỗi vì sự nhầm lẫn. Vui lòng xem mã mẫu bổ sung mà tôi vừa đăng để cố gắng làm những gì bạn nói. Nó hoạt động bằng cách sử dụng 'DOMElement', nhưng không phải với lớp mở rộng' FreezableDOMElement'. – neizan