웹 페이지에서 계층 적 데이터를 스크랩하고 DB에 저장하도록 설계된 PHP 프로젝트를 자주 수행합니다 (본질적으로 데이터 구조화 - 데이터는 구조화 된 방식으로 제공하지 않음). 원래 웹 페이지가 PHP OOP 디자인 - 일반 인터페이스를 구현하는 동안 특정 하위 클래스에 매개 변수 제한
- 쉽게 새 것으로 현재 HTML 구문 분석 스크립트를 바꿉니다 때마다, 나는 나에게 다음과 같은 달성 할 수있는 것 인 OOP 디자인을 마련하려고 이 프로젝트는 다른 사람들이 데이터를 수집하고 빌드하는 데에도 사용되므로 데이터를 스크랩하고 저장해야합니다. 내 목표는 "기본"데이터를 수집하는 것입니다. 다른 사람들은 무언가를 추가하거나 저장 방법을 변경하기도합니다.
지금까지 솔루션을 찾지 못했지만 가장 가까운 곳은 이런 식으로 뭔가 :
내가 일반적인 나무 이송 기능을 구현하는 것이 데이터 컨테이너에 대한 추상 클래스를 정의abstract class DataContainer {
protected $parent = NULL;
protected $children = NULL;
public function getParent() {
return $this->parent;
}
public function getChildren() {
return $this->children;
}
}
그리고 나서 실제 데이터 컨테이너가 있습니다. 상원 의원 회의에서의 참여에 관한 자료를 "앉아있는 특정 질문"수준으로 내려고 상상해보십시오. SessionContainer
, SittingContainer
, QuestionContainer
은 모두 DataContainer
입니다.
각 세션, 앉기 및 질문 데이터는 다른 URL에서 스크랩됩니다. URL 컨텐트를 가져 오는 메커니즘을 떠나서, 실제로 컨테이너를 가져 오는 스크래퍼 클래스와 실제 구문 분석을위한 DOmDocument가 필요하다고 가정 해 봅시다. , 그리고 세션의 각을
interface Scraper {
public function scrapeData(DOMDocument $Dom, DataContainer $DataContainer);
}
을 앉아 문제는 인터페이스를 구현 자신의 스크레이퍼를했을 : 그래서 나는이 같은 일반적인 인터페이스를 정의한다. 그러나 나는 또한 그들이 의미하는 용기 만 받아 들일 수 있도록하고 싶다. 마지막으로
class SessionScraper implements Scraper {
public function scrapeData(DOMDocument $DOM, SessionContainer $DataContainer) {
}
}
, 나는 또한 스크레이퍼 인터페이스를 구현하고 단지 관련 스크레이퍼로 긁어를 배포하는 일반적인 Factory
클래스있을 것입니다 :처럼 그래서 보일 것이다. 이와 같이 :
public function scrapeData(DOMDocument $DOM, DataContainer $DataContainer) {
//get the scraper from configuration array
$class = $this->config[get_class($DataContainer)];
$craper = new $class();
$class->scrapeData($DOM, $DataContainer);
}
이것은 실제로 코드에서 호출되는 클래스입니다. 매우 비슷하게 DB에 저장하는 방법도 있습니다. 각 데이터 컨테이너에는 DBSaver 인터페이스가 구현되는 DBSaver 클래스가있을 수 있습니다. 다시 말하지만, 모든 호출은 DBSaver 인터페이스를 구현하는 Factory
클래스를 통해 수행 될 수 있습니다.
모든 것이 완벽하지만 문제는 인터페이스를 구현하는 클래스가 인터페이스의 정확한 서명을 구현해야한다는 것입니다. 예 : 메서드 SessionScraper::scrapeData
은 만 허용되며SessionContainer
개체는 모두 DataContainer
개체를 받아 들여야합니다. 그러나 그것은 의미가 아닙니다! 마지막으로
질문 :
- 내 디자인은 잘못이고 나는 완전히 다른 방식으로 모든 것을 구조화해야 하는가? (방법?) 또는 :
- 내 디자인이 괜찮습니다. 형식화를 통해
instanceof
및 이와 유사한 검사를 사용하는 대신 형식을 적용해야합니다.
모든 제안/비평에 대해 미리 감사드립니다. 필자는 필요한 경우이 코드를 머리에 뒤집어 쓰는 사람에게 매우 만족합니다!
광범위한 답변을 주셔서 감사합니다. 몇 가지 다른 아이디어도 제시되었습니다. 한 가지 설명 - 모든 데이터를 유지하는 데 하나의 데이터/컨테이너 클래스를 사용하고 하위 클래스를 만드는 대신 유형 속성별로 식별하는 것이 좋습니다. 또는 두 유형의 속성 및 하위 클래스가 될 것이고, 스크래퍼는 유형 만 고려할 것입니다. – Aurimas
귀하의 데이터를 구체적으로 알지 못하므로 알기가 어렵습니다. 데이터가 매우 공통적 인 경우에만 다른 속성을 가지고, 당신은 많은 데이터 클래스를 만들 필요가 없습니다, 당신은 동적 속성과 함께 갈 수 있습니다. 나중에 전체 응용 프로그램에서 훨씬 좋습니다. 주로 스크래퍼가 변경되며 때로는 데이터가 변경됩니다. 일부 웹 사이트가 조금 변경 되었기 때문에 항상 새로운 데이터 클래스를 만들어야합니다. 안좋다 :) – hakre