sweetrdf/rdf-interface
Common RDF interfaces for PHP (PSR-7-like): define shared contracts for terms, datasets, parsers/serializers, SPARQL clients, etc., enabling mix-and-match components across libraries. Includes compliance tests and helpers; influenced by RDF/JS.
Installation:
composer require sweetrdf/rdf-interface
Pair with a reference implementation (e.g., quickRdf or simpleRdf):
composer require sweetrdf/quickrdf sweetrdf/quickrdfio
First Use Case:
Parse an RDF file (e.g., Turtle) into a Dataset:
use SweetRdf\RdfInterface\ParserInterface;
use SweetRdf\QuickRdfIo\Parser;
$parser = new Parser();
$dataset = $parser->parse(file_get_contents('data.ttl'), 'http://example.org/data');
Key Entry Points:
DataFactory: Create terms (URIs, literals, blank nodes).Dataset: Core interface for RDF operations (add/remove quads, filtering).Serializer: Export to formats like Turtle/NTriples.Term Creation:
Use DataFactory to create immutable terms:
$factory = new \SweetRdf\QuickRdf\DataFactory();
$subject = $factory->namedNode('http://example.org/subject');
$predicate = $factory->namedNode('http://example.org/predicate');
$object = $factory->literal('value', 'en');
$quad = $factory->quad($subject, $predicate, $object);
Dataset Operations:
$dataset->add($quad);
$dataset->delete($factory->quadTemplate($subject, $predicate, null, null));
QuadCompare (e.g., QuadTemplate) for SPARQL-like queries:
$filtered = $dataset->copy($factory->quadTemplate($subject, null, null, null));
Streaming I/O: Parse/serialize streams for large datasets:
$parser->parseStream(fopen('data.ttl', 'r'), 'http://example.org/data');
$serializer->serializeStream($dataset, fopen('output.ttl', 'w'));
Node-Oriented Operations:
Use DatasetNode for subject-centric queries:
$node = $dataset->node($subject);
$node->getPredicate()->forEach(fn($p) => $node->getObject($p));
SPARQL Clients:
Combine with sweetrdf/sparqlClient for remote queries:
$client = new \SweetRdf\SparqlClient\Client('https://query.wikidata.org/sparql');
$results = $client->query('SELECT * WHERE { ?s ?p ?o } LIMIT 10');
Template Libraries:
Use termTemplates for reusable filters:
$template = new \SweetRdf\TermTemplates\QuadTemplate($subject, $predicate, null, null);
EasyRdf Migration:
Use rdfInterface2easyRdf for interoperability:
$converter = new \SweetRdf\RdfInterface2EasyRdf\Converter();
$easyRdfGraph = $converter->toEasyRdf($dataset);
Immutability:
Terms (e.g., NamedNode, Literal) are immutable. Avoid direct property modification—use DataFactory to create modified copies:
// ❌ Avoid:
$subject->uri = 'new-uri'; // Fails (immutable)
// ✅ Do:
$newSubject = $factory->namedNode('new-uri');
Blank Node Handling:
$baseUri to parsers for correct blank node resolution:
$parser->parse($data, 'http://example.org'); // ✅ Correct
$parser->parse($data); // ❌ May fail for blank nodes
ParserInterface::BLANK_NODES_PRESERVE for edge cases (e.g., RDF-XML):
$parser->parse($data, ParserInterface::BLANK_NODES_PRESERVE);
Dataset Access:
$dataset[0]) throws MultipleQuadsMatchedException if ambiguous. Use filtering:
$quad = $dataset->copy($factory->quadTemplate($subject, null, null, null))->current();
Type Safety:
getPredicate() return NamedNodeInterface|null. Handle null explicitly:
$predicate = $dataset->getPredicate($subject, $object);
if ($predicate === null) { /* Handle missing */ }
Term Comparison:
Use TermCompareInterface for equality checks:
if ($term1->equals($term2)) { /* ... */ }
Dataset Validation:
Run compliance tests (rdfInterfaceTests) to verify implementations:
composer require sweetrdf/rdfinterface-tests
vendor/bin/phpunit --testsuite SweetRdf\RdfInterfaceTests
Performance:
TermInterface caching (e.g., via DataFactory) for repeated terms.Custom Terms:
Extend TermInterface for domain-specific terms (e.g., RDF-Star):
class RdfStarTerm implements TermInterface, TermCompareInterface { /* ... */ }
Dataset Decorators:
Wrap DatasetInterface to add logic (e.g., logging, validation):
class LoggingDataset implements DatasetInterface {
private $dataset;
public function __construct(DatasetInterface $dataset) { $this->dataset = $dataset; }
public function add(QuadInterface $quad) {
error_log("Adding quad: " . $quad);
$this->dataset->add($quad);
}
// Delegate other methods...
}
Parser/Serializer Extensions:
Implement ParserInterface/SerializerInterface for new formats (e.g., JSON-LD):
class JsonLdParser implements ParserInterface {
public function parse(string $data, ?string $baseUri = null): DatasetInterface { /* ... */ }
}
QuadTemplates:
Create reusable filters with QuadCompare:
class DateRangeTemplate implements QuadCompare {
public function __construct(private \DateTimeInterface $start, private \DateTimeInterface $end) {}
public function equals(QuadCompare $other): bool { /* ... */ }
public function getSubject(): ?TermInterface { return null; } // Filter on predicate/object
// Implement other QuadCompare methods...
}
PSR-7 Compatibility:
Psr7Stream for HTTP-based I/O (e.g., with sparqlClient):
use SweetRdf\RdfHelpers\Psr7Stream;
$stream = new Psr7Stream(fopen('data.ttl', 'r'));
$parser->parseStream($stream, 'http://example.org');
Base URI Handling:
$baseUri only for in-memory datasets. Always provide it for file/HTTP sources.Default Graphs:
DataFactory::defaultGraph() for quads without a named graph:
$quad = $factory->quad($subject, $predicate, $object, $factory->defaultGraph());
Literal Datatypes:
$literal = $factory->literal('123', 'http://www.w3.org/2001/XMLSchema#integer');
How can I help you explore Laravel packages today?