PHP 5.3 or later. Might work on earlier PHP 5.x versions. Java version is in the works.
Graphity is a fully object-oriented PHP framework for building flexible RESTful, Semantic Web, and/or Linked Data web applications.
Graphity tries not to invent new conventions, but instead to combine existing ones. It is based on W3C standards and reuses Java APIs where possible.
Supports JAX-RS-style RESTful API:
- resource annotations like
@Pathand@GET UriBuilderfor building URIs out of components (includes implementation in JavaScript)ResponseBuilderfor buildingResponseobjects
Further implementation of missing JAX-RS features is planned.
Supports Jena-style object-oriented RDF API:
Model- RDF/XML (DOM) serialization
- Turtle serialization
StatementResourceLiteral
Includes utility classes for dealing with SPARQL, RDF/XML, and XSLT:
Repositoryfor remote SPARQL 1.1 endpoint accessQueryBuilderfor building SPARQL queriesRDFFormfor reading requests in RDF/POST encodingMultipartParserandMultipartRequestfor readingmultipart/form-datarequests (PHP port of O'Reilly's Multipart classes)XSLTBuilderfor building XSLT transformations (PHP's XSL extension must be enabled)DOM2Modelfor converting RDF/XML to Model (reverse ofModel::toDOM())
To create a Graphity PHP application, you need to follow similar steps as in creating JAX-RS webapp, plus some extra steps because of PHP's interpreted and per-request nature:
-
Checkout or extract graphity-core into
/lib/graphity-coreor similar folder in your project. We recommend choosing the latest version tag on GitHub.We strongly recommend Maven Standard Directory Layout, as it will be easier to share reusable resources with the Java version in the future. It is used in the following examples.
-
Create some resource class that imports and extends
Graphity\Resource, for example:namespace My; use Graphity\Response; use Graphity\ResponseBuilder; use Graphity\View\ContentType; class Resource extends \Graphity\ResourceWe strongly recommend using PHP namespaces with the standard folder layout. In Maven structure, that would be within the
src/main/phpfolder. It is used in the following examples. -
Annotate the class with
@Pathand methods with@GET/@POSTetc., for example:namespace My; use Graphity\Response; use Graphity\ResponseBuilder; use Graphity\View\ContentType; /** * @Path("/hello") */ class Resource extends \Graphity\Resource { /** * @GET * @Produces("text/html") */ public function getResponse() { return ResponseBuilder::newInstance()-> entity("<html>Hello ". $this->getRequest()->getParameter("what") ."!</html>")-> status(Response::SC_OK)-> type(ContentType::TEXT_HTML)-> build(); } }This class would match GET requests on
/hellopath and print a statement depending on thewhatquery parameter value.PHP annotations must be embedded in
/* */comment blocks.@Produces/@Consumesannotations are not yet fully supported, but we recommend adding them for future compatibility. -
Run
/lib/graphity-core/bin/route_mapper.phpspecifying the root folder of your namespace and the location of your route map file, for example (paths are relative to project root in this case):$ php lib/graphity-core/bin/route_mapper.php src/main/php/My src/main/php/routes.phpThis should scan your resource classes and generate a route map file, which is used internally by Graphity to match request URIs against JAX-RS annotations. This does not happen dynamically (as of yet), you have to re-map routes with
route_mapper.phpevery time your annotations change. -
Implement a subclass of
Graphity\Application:namespace My; class Application extends \Graphity\Application { public function __construct() { parent::__construct(include(dirname(dirname(__FILE__)) . "/routes.php")); $loader = new \Graphity\Loader("My", dirname(dirname(__FILE__))); $loader->register(); } }This class initializes route map and
Graphity\Loaderand can be used for custom initializations. -
Make an entry point to your
Applicationlikeindex.phpand put it undersrc/main/webapp:define('ROOTDIR', dirname(dirname(dirname(dirname(__FILE__))))); require_once(ROOTDIR . '/lib/graphity-core/src/main/php/Graphity/Application.php'); require_once(ROOTDIR . '/src/main/php/My/Application.php'); $app = new My\Application(); $app->run();The
Graphity\Application::run()method will do the processing for you, executing the whole HTTP workflow from receiving aGraphity\Requestto writing out aGraphity\Response. Later you might want to override it withMy\Application::run()method to include atry/catchblock forGraphity\WebApplicationExceptionhandling.Both
Applicationsuperclass and subclass need to be included here to bootstrap the framework.This should be the single and only entry point to your Graphity web application.
-
Fix URL rewriting by adding
.htaccessconfiguration undersrc/main/webapp:RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_URI} !\.(js|ico|gif|jpg|png|css|swf)$ [NC] RewriteRule ^(.*)$ index.php/$1 [L]Requests with
multipart/form-datacontent type should not be accessed via PHP's$_FILEor similar methods, and instead used with Graphity'sMultipartRequestandMultipartParserclasses. The following instructions make this possible by setting request content type tomultipart/form-data-alternatebefore it is passed to PHP, and can be placed invhost.conf:<Location /> SetEnvIf Content-Type ^(multipart/form-data)(.*) NEW_CONTENT_TYPE=multipart/form-data-alternate$2 OLD_CONTENT_TYPE=$1$2 RequestHeader set Content-Type %{NEW_CONTENT_TYPE}e env=NEW_CONTENT_TYPE </Location> -
Ready? Launch! Open http://localhost/hello?what=world in your browser and you should see
Hello world!printed out for you. Naturally the base URI in this example depends on your webserver and/or virtual host configuration.
We need to do some work on this... Check out our issues so far.
W3C "Linked Enterprise Data Patterns" workshop
Graphity core is licensed under Apache License 2.0.
Graphity PHP core uses following 3rd party libraries:
- Addendum (for annotation parsing)