hardf هي مكتبة PHP 7.1+ تتيح لك التعامل مع البيانات المرتبطة (RDF). وهو يقدم:
يتمتع كل من المحلل اللغوي والمُسلسِل بدعم البث .
هذه المكتبة هي منفذ N3.js إلى PHP
نستخدم التمثيل الثلاثي في PHP المنقول من مكتبة NodeJS N3.js. راجع https://github.com/rdfjs/N3.js/tree/v0.10.0#triple-representation لمزيد من المعلومات
عمدنا إلى التركيز على الأداء، وليس على سهولة المطورين. لقد قمنا بالتالي بتنفيذ هذا التمثيل الثلاثي باستخدام المصفوفات الترابطية بدلاً من كائن PHP. وهكذا، فإن نفس الشيء الذي ينطبق على N3.js، أصبح الآن مصفوفة. على سبيل المثال:
<?php
$ triple = [
' subject ' => ' http://example.org/cartoons#Tom ' ,
' predicate ' => ' http://www.w3.org/1999/02/22-rdf-syntax-ns#type ' ,
' object ' => ' http://example.org/cartoons#Cat ' ,
' graph ' => ' http://example.org/mycartoon ' , #optional
];
قم بتشفير القيم الحرفية على النحو التالي (على غرار N3.js)
' "Tom"@en-gb ' // lowercase language
'" 1 "^^http: //www.w3.org/2001/XMLSchema#integer' // no angular brackets <>
قم بتثبيت هذه المكتبة باستخدام الملحن:
composer require pietercolpaert/ hardf
use pietercolpaert hardf TriGWriter ;
فئة يجب إنشاء مثيل لها ويمكنها كتابة TriG أو Turtle
مثال على الاستخدام:
$ writer = new TriGWriter ([
" prefixes " => [
" schema " => " http://schema.org/ " ,
" dct " => " http://purl.org/dc/terms/ " ,
" geo " => " http://www.w3.org/2003/01/geo/wgs84_pos# " ,
" rdf " => " http://www.w3.org/1999/02/22-rdf-syntax-ns# " ,
" rdfs " => " http://www.w3.org/2000/01/rdf-schema# "
],
" format " => " n-quads " //Other possible values: n-quads, trig or turtle
]);
$ writer -> addPrefix ( " ex " , " http://example.org/ " );
$ writer -> addTriple ( " schema:Person " , " dct:title " , "" Person " @en " , " http://example.org/#test " );
$ writer -> addTriple ( " schema:Person " , " schema:label " , "" Person " @en " , " http://example.org/#test " );
$ writer -> addTriple ( " ex:1 " , " dct:title " , "" Person1 " @en " , " http://example.org/#test " );
$ writer -> addTriple ( " ex:1 " , " http://www.w3.org/1999/02/22-rdf-syntax-ns#type " , " schema:Person " , " http://example.org/#test " );
$ writer -> addTriple ( " ex:2 " , " dct:title " , "" Person2 " @en " , " http://example.org/#test " );
$ writer -> addTriple ( " schema:Person " , " dct:title " , "" Person " @en " , " http://example.org/#test2 " );
echo $ writer -> end ();
//The method names should speak for themselves:
$ writer = new TriGWriter ([ " prefixes " : [ /* ... */ ]]);
$ writer -> addTriple ( $ subject , $ predicate , $ object , $ graphl );
$ writer -> addTriples ( $ triples );
$ writer -> addPrefix ( $ prefix , $ iri );
$ writer -> addPrefixes ( $ prefixes );
//Creates blank node($predicate and/or $object are optional)
$ writer -> blank ( $ predicate , $ object );
//Creates rdf:list with $elements
$ list = $ writer -> addList ( $ elements );
//Returns the current output it is already able to create and clear the internal memory use (useful for streaming)
$ out .= $ writer -> read ();
//Alternatively, you can listen for new chunks through a callback:
$ writer -> setReadCallback ( function ( $ output ) { echo $ output });
//Call this at the end. The return value will be the full triple output, or the rest of the output such as closing dots and brackets, unless a callback was set.
$ out .= $ writer -> end ();
//OR
$ writer -> end ();
بجانب TriG، تقوم فئة TriGParser أيضًا بتحليل Turtle وN-Triples وN-Quads وW3C Team Submission N3
$ parser = new TriGParser ( $ options , $ tripleCallback , $ prefixCallback );
$ parser -> setTripleCallback ( $ function );
$ parser -> setPrefixCallback ( $ function );
$ parser -> parse ( $ input , $ tripleCallback , $ prefixCallback );
$ parser -> parseChunk ( $ input );
$ parser -> end ();
استخدام قيم الإرجاع وتمريرها إلى الكاتب:
use pietercolpaert hardf TriGParser ;
use pietercolpaert hardf TriGWriter ;
$ parser = new TriGParser ([ " format " => " n-quads " ]); //also parser n-triples, n3, turtle and trig. Format is optional
$ writer = new TriGWriter ();
$ triples = $ parser -> parse ( " <A> <B> <C> <G> . " );
$ writer -> addTriples ( $ triples );
echo $ writer -> end ();
استخدام عمليات الاسترجاعات وتمريرها إلى الكاتب:
$ parser = new TriGParser ();
$ writer = new TriGWriter ([ " format " => " trig " ]);
$ parser -> parse ( " <http://A> <https://B> <http://C> <http://G> . <A2> <https://B2> <http://C2> <http://G3> . " , function ( $ e , $ triple ) use ( $ writer ) {
if (! isset ( $ e ) && isset ( $ triple )) {
$ writer -> addTriple ( $ triple );
echo $ writer -> read (); //write out what we have so far
} else if (! isset ( $ triple )) // flags the end of the file
echo $ writer -> end (); //write the end
else
echo " Error occured: " . $ e ;
});
عندما تحتاج إلى تحليل ملف كبير، ستحتاج إلى تحليل الأجزاء فقط ومعالجتها بالفعل. يمكنك القيام بذلك على النحو التالي:
$ writer = new TriGWriter ([ " format " => " n-quads " ]);
$ tripleCallback = function ( $ error , $ triple ) use ( $ writer ) {
if ( isset ( $ error ))
throw $ error ;
else if ( isset ( $ triple )) {
$ writer -> write ();
echo $ writer -> read ();
else if ( isset ( $ error )) {
throw $ error ;
} else {
echo $ writer -> end ();
}
};
$ prefixCallback = function ( $ prefix , $ iri ) use (& $ writer ) {
$ writer -> addPrefix ( $ prefix , $ iri );
};
$ parser = new TriGParser ([ " format " => " trig " ], $ tripleCallback , $ prefixCallback );
$ parser -> parseChunk ( $ chunk );
$ parser -> parseChunk ( $ chunk );
$ parser -> parseChunk ( $ chunk );
$ parser -> end (); //Needs to be called
format
(غير حساس لحالة الأحرف)turtle
- سلحفاةtrig
- مثلث المثلثtriple
، على سبيل المثال triple
، ntriples
، N-Triples
- N-Triplesquad
، على سبيل المثال quad
، nquads
، N-Quads
- N-Quadsn3
، على سبيل المثال n3
- N3blankNodePrefix
(البادئة الافتراضية b0_
) المفروضة على أسماء العقد الفارغة، على سبيل المثال TriGWriter(["blankNodePrefix" => 'foo'])
سوف تقوم بتحليل _:bar
كـ _:foobar
.documentIRI
بتعيين عنوان URI الأساسي المستخدم لحل معرفات URI النسبية (لا ينطبق إذا كان format
يشير إلى n-triples أو n-quads)lexer
باستخدام فئة lexer الخاصة. يجب على المعجم توفير الطرق العامة التالية:tokenize(string $input, bool $finalize = true): array<array{'subject': string, 'predicate': string, 'object': string, 'graph': string}>
tokenizeChunk(string $input): array<array{'subject': string, 'predicate': string, 'object': string, 'graph': string}>
end(): array<array{'subject': string, 'predicate': string, 'object': string, 'graph': string}>
explicitQuantifiers
- [...] قد تستخدم بعض مستندات Turtle وN3 صيغة IRI النسبية للقاعدة (انظر هنا وهنا)، على سبيل المثال
<> <someProperty> "some value" .
لتحليل هذه المستندات بشكل صحيح، يجب أن يكون IRI الأساسي للمستندات معروفًا. وإلا فقد ينتهي بنا الأمر مع IRIs فارغة (على سبيل المثال، للموضوع في المثال أعلاه).
في بعض الأحيان يتم ترميز IRI الأساسي في المستند، على سبيل المثال
@base <http://some.base/iri/> .
<> <someProperty> "some value" .
ولكن في بعض الأحيان يكون مفقودا. في مثل هذه الحالة، تتطلب مواصفات Turtle منا اتباع القسم 5.1.1 من RFC3986 الذي ينص على أنه إذا لم يتم تضمين IRI الأساسي في المستند، فيجب افتراض أنه هو URI لاسترجاع المستند (على سبيل المثال، عنوان URL الذي قمت بتنزيل المستند به) من أو مسار ملف تم تحويله إلى عنوان URL). لسوء الحظ، لا يمكن للمحلل اللغوي hardf تخمين ذلك ويجب توفيره بواسطتك باستخدام خيار إنشاء المحلل اللغوي documentIRI
، على سبيل المثال
parser = new TriGParser ([ " documentIRI " => " http://some.base/iri/ " ]);
قصة قصيرة طويلة إذا واجهت subject/predicate/object on line X can not be parsed without knowing the the document base IRI.(...)
يرجى تهيئة المحلل اللغوي باستخدام خيار documentIRI
.
use pietercolpaert hardf Util ;
فئة ثابتة تحتوي على وظيفتين مفيدتين للتعامل مع تمثيلنا الثلاثي المحدد. سيساعدك ذلك على إنشاء وتقييم القيم الحرفية وIRIs وتوسيع البادئات.
$ bool = isIRI ( $ term );
$ bool = isLiteral ( $ term );
$ bool = isBlank ( $ term );
$ bool = isDefaultGraph ( $ term );
$ bool = inDefaultGraph ( $ triple );
$ value = getLiteralValue ( $ literal );
$ literalType = getLiteralType ( $ literal );
$ lang = getLiteralLanguage ( $ literal );
$ bool = isPrefixedName ( $ term );
$ expanded = expandPrefixedName ( $ prefixedName , $ prefixes );
$ iri = createIRI ( $ iri );
$ literalObject = createLiteral ( $ value , $ modifier = null );
راجع الوثائق على https://github.com/RubenVerborgh/N3.js#utility لمزيد من المعلومات.
نحن نقدم أيضًا أداتين بسيطتين في bin/
كمثال للتنفيذ: مدقق واحد ومترجم واحد. حاول على سبيل المثال:
curl -H " accept: application/trig " http://fragments.dbpedia.org/2015/en | php bin/validator.php trig
curl -H " accept: application/trig " http://fragments.dbpedia.org/2015/en | php bin/convert.php trig n-triples
قمنا بمقارنة الأداء في ملفين من ملفات السلاحف، وقمنا بتحليله باستخدام مكتبة EasyRDF في PHP، ومكتبة N3.js لـ NodeJS ومع hardf . وكانت هذه النتائج:
#ثلاثية | نطاق | الوقت (مللي ثانية) | الذاكرة (ميجابايت) |
---|---|---|---|
1,866 | hardf بدون opcache | 27.6 | 0.722 |
1,866 | hardf مع opcache | 24.5 | 0.380 |
1,866 | EasyRDF بدون opcache | 5,166.5 | 2.772 |
1,866 | EasyRDF مع opcache | 5,176.2 | 2.421 |
1,866 | ARC2 مع opcache | 71.9 | 1.966 |
1,866 | N3.js | 24.0 | 28.xxx |
3,896,560 | hardf بدون opcache | 40,017.7 | 0.722 |
3,896,560 | hardf مع opcache | 33,155.3 | 0.380 |
3,896,560 | N3.js | 7,004.0 | 59.xxx |
3,896,560 | ARC2 مع opcache | 203,152.6 | 3,570.808 |
مكتبة hardf محمية بحقوق الطبع والنشر بواسطة Ruben Verborgh وPieter Colpaert وتم إصدارها بموجب ترخيص MIT.
نرحب بالمساهمات، وتكون تقارير الأخطاء أو طلبات السحب مفيدة دائمًا. إذا كنت تخطط لتنفيذ ميزة أكبر، فمن الأفضل مناقشة ذلك أولاً عن طريق تقديم مشكلة.