Ik wil graag wat feedback over mijn manier van denken. Ik ben op school nu bezig om a.d.h.v. Java de basisprincipes van het object georiënteerd programmeren aan te leren, en wou nu al het één en ander toepassen in een relatief zinvol PHP script omdat ik van mening ben dat ik daar wel aan toe ben.
Het probleem is dat me eigenlijk nog niet geleerd is hoe ik klassen moet ontwerpen, maar aangezien dit best een simpel voorbeeld is (denk ik..) durf ik me er wel aan te wagen.
Ik hou van het maken van foto's en programmeren. Nu wou ik die twee hobby's combineren dus ik had bedacht om een remote shooting script te schrijven. Nu heb ik onder Linux het programma "gphoto2" geïnstalleerd, dit werkt uitstekend en het stelt me in staat om m'n spiegelreflex op een afstand te besturen.
Nu wil ik zorgen dat ik vanaf een PHP script deze software kan besturen. Nu weet ik wel dat dat met shell_exec() uitstekend gaat en is het me ook al gelukt om een OOP PHP script te schrijven dat prima werkt (zie http://mcdronkz.ath.cx/remotecapture/ password is "fahrftw") maar de klassen steken volgens mij onlogisch in elkaar en daar hoop ik door dit topic wat verandering in te brengen.
Ik wil het vanaf nu wat meer to the point gaan houden want ik begrijp dat bovenstaand stukje misschien een beetje te uitgebreid is beschreven, dus hier komt 'ie.
Eerst even kijken welke objecten ik nodig heb:
Ik heb een programma genaamd gphoto, deze is aan één of meerdere camera's gekoppeld, de geselecteerde camera moet een foto maken nadat iemand het goede wachtwoord heeft ingegeven.
Hier haal ik sowieso de volgende objecten uit: camera, foto, authenticatie.
Laten we beginnen met de makkelijkste, authenticatie:
<?php
/*
Het is niet nodig om hier een instance van te maken, daarom gebruik ik een static class.
*/
static class Authentication () {
$password = "sdghsd235235uwdhghsdgs32523"; //MD5 string
public static function checkPassword($password) {
/*
Deze controleert of md5($password) gelijk is aan $this->password en returned uiteindelijk true of false.
*/
}
}
?>
Ok, dan hebben we die gehad.
Dan krijgen we de camera. We willen dus één of meerdere camera's kunnen bedienen. Ik denk dat ik daarvoor een handler nodig heb, maar dat is van latere zorg.
<?php
class Camera () {
private $model; //Model is het merk en type van de camera, hiermee kun je meerdere camera's onderscheiden.
function __construct($model) {
setModel($model);
}
public function setModel($model) {
$this->model = $model;
}
public function getModel() {
return $this->model;
}
public function captureAndDownloadPicture($filename) {
/*
Maak een foto en sla deze op de schijf op met de ingegeven bestandsnaam. Maak vervolgens een instance van een picture en return deze.
*/
$picture = new Picture($filename);
return $picture; //$picture is van het type picture
}
public function getAperture() {
}
public function getShuttertime() {
}
public function getISOSpeed() {
}
}
?>
Ik denk dat ik wat betreft de camera zo aardig compleet ben. Nu moet ik nog meerdere camera's kunnen bedienen, en dat wou ik met een cameraHandler object gaan doen. Het is overigens de bedoeling dat het procedurele gedeelte deze klasse rechtstreeks aanroept, en hier een instance van maakt. Dit is wel iets waarvan ik niet helemaal zeker ben, dus input is zeker gewenst hier.
<?php
class cameraHandler () {
private $cameras = array(); //Array waar camera objecten in komen te staan.
function __construct() {
/*
Maak instances van de camera objecten en plaats deze in $this->cameras.
*/
}
public function getCameras() {
return $this->cameras;
}
public function getPicture($model) {
/*
Vooral over deze functie ben ik onzeker. Het is de bedoeling dat ik straks de foto kan resizen en dergelijke, en
het lijkt me niet dat cameraHandler deze verantwoordelijkheid krijgt. Daarom ga ik straks een picture klasse en een
pictureHandler klasse schrijven. De camera maakt een instance van een picture, die ik hier vervolgens met een statische
pictureHandler object kan bewerken.
*/
if(in_array($model, $this->cameras)) {
$filename = "pictures/".time().".jpg";
if(($picture = $this->cameras[$model]->captureAndDownloadPicture($filename)) != false) {
pictureHandler::setPermissions($picture);
pictureHandler::resizePicture($picture);
pictureHandler::putLabelOnPicture($picture);
return $picture;
}
}
/*
Return false als het niet gelukt is om een foto te maken.
*/
return false;
}
}
?>
Dan moeten we dus een picture klasse maken, deze bevat de bestandsnaam van de afbeelding maar kan in de toekomst natuurlijk uitgebreid worden met EXIF informatie return functies en dat soort zaken.
<?php
class Picture () {
private $filename;
function __construct($filename) {
setFilename($filename);
}
public function setFilename($filename) {
$this->filename = $filename;
}
public function getFilename() {
return $this->filename;
}
}
?>
En dan de pictureHandler:
<?php
static class pictureHandler() {
public static function setPermissions() {
}
public static function resizePicture() {
}
public static function putLabelOnPicture() {
}
}
?>
Dan zou je het volgende stukje procuderele code kunnen gebruiken:
<?php
$handler = new cameraHandler();
if($_SERVER['REQUEST_METHOD'] == "POST") {
if(Authentication::checkPassword($_POST['password'])) {
if(($picture = $handler->getPicture($_POST['model']) != false)) {
echo "Er is een foto gemaakt met de volgende filename: ".$picture->getFilename();
} else {
echo "Er ging iets fout tijdens het maken van de foto.";
}
} else {
echo "Voer het correcte wachtwoord in.";
}
} else {
/*
Toon een formulier met de camera's die gekozen kunnen worden en waar het wachtwoord ingevoerd kan worden.
*/
}
?>
Is dit nou de juiste approach ? Ik moet je eerlijk zeggen dat het behoorlijk lang geduurd heeft om deze vraag op te stellen omdat het voor mij nog moeilijk is om de relaties tussen verschillende objecten te zien en te bepalen. De code die ik hier geschreven heb kan ik voor mezelf wel rijmen denk ik, als ik kijk wat het doet is het voor mij vrij logisch.
Toch wou ik graag jullie kijk erop.
1.408 views
:-)