Ready for the next step?
Use the PHP School workshop documentation to build you own workshop and help teach others PHP!
Open Menu
This article documents each of the checks bundled with the workshop framework and how to use them. Remember the exercise types from the Exercise Types documentation? CLI, CGI & CUSTOM?
Well, checks can support one or more of these exercise types types. So inspect the table below to see if the check you want to use actually supports your exercise type.
PhpSchool\PhpWorkshop\Exercise\ExerciseInterface
Simple
CLI, CGI
Note: You do not need to require this check yourself, it is done so automatically.
PhpSchool\PhpWorkshop\Exercise\ExerciseInterface
Simple
CLI, CGI
Note: You do not need to require this check yourself, it is done so automatically.
PhpSchool\PhpWorkshop\Exercise\ExerciseInterface
Simple
CLI, CGI
php -l <submission-file>
.Note: You do not need to require this check yourself, it is done so automatically.
PhpSchool\PhpWorkshop\ExerciseCheck\FunctionRequirementsExerciseCheck
Simple
CLI, CGI
PhpSchool\PhpWorkshop\ExerciseCheck\ComposerExerciseCheck
Simple
CLI, CGI
composer.lock
files exists and contains entries
for the required packages.
PhpSchool\PhpWorkshop\ExerciseCheck\DatabaseExerciseCheck
Listener
CLI, CGI
PDO
object. It prepends the database DSN as a
CLI argument to the student's solution so they can connect to the database. The PDO
object
is passed to the exercise before and after the student's solution has been executed, allowing you to
first seed the database and then verify the contents of the database.Here is an example of how to force the student to use the function curl_exec
and ban the usage of
file_get_contents
. This could be useful if you wanted to teach advanced configuration of data transfers.
class MyExercise extends AbstractExercise
implements ExerciseInterface, FunctionRequirementsExerciseCheck
{
...snip
/**
* @param ExerciseDispatcher $dispatcher
*/
public function configure(ExerciseDispatcher $dispatcher)
{
$dispatcher->requireCheck(FunctionRequirementsCheck::class);
}
/**
* @return string[]
*/
public function getRequiredFunctions()
{
return ['curl_exec'];
}
/**
* @return string[]
*/
public function getBannedFunctions()
{
return ['file_get_contents'];
}
}
If a student submitted something like:
<?php
echo file_get_contents('http://example.com');
The output would be something along the lines of:
Here is an example of how to force the student to require the nikic/fast-route
package via Composer. This
is useful if you want to focus on a specific problem or promote popular/battle tested packages.
class MyExercise extends AbstractExercise
implements ExerciseInterface, ComposerExerciseCheck
{
...snip
/**
* @param ExerciseDispatcher $dispatcher
*/
public function configure(ExerciseDispatcher $dispatcher)
{
$dispatcher->requireCheck(ComposerCheck::class);
}
/**
* @return array
*/
public function getRequiredPackages()
{
return [
'nikic/fast-route'
];
}
}
A number of failures can occur here, the student may not even have a composer.json
or
a composer.lock
file. If this is the
case, the check will fail and a message will be printed. If the required files are present, but the
package has not been found, the output will look like the following:
Here is an example where we require that the student insert a record in to the users
table which we
will create in the seed
method of our check. We will then verify that there are some records in the
users
table.
class MyExercise extends AbstractExercise
implements ExerciseInterface, DatabaseExerciseCheck
{
...snip
/**
* @param ExerciseDispatcher $dispatcher
*/
public function configure(ExerciseDispatcher $dispatcher)
{
$dispatcher->requireCheck(DatabaseCheck::class);
}
/**
* @param PDO $db
* @return void
*/
public function seed(PDO $db)
{
$db->exec('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER, gender TEXT)');
}
/**
* @param PDO $db
* @return bool
*/
public function verify(PDO $db)
{
return $db->query('select COUNT(*) from users')->fetchColumn() > 0;
}
}
If the student did not insert into the database, for example, if they submitted the following:
<?php
echo "Where is the database?";
Then they would receive the following failure:
If they submitted a proper solution, like the following:
<?php
$dsn = $argv[1];
$db = new PDO($dsn);
$stmt = $db->prepare('INSERT INTO users (name, age, gender) VALUES (:name, :age, :gender)');
$stmt->execute([':name' => 'Karl Renner', ':age' => 80, ':gender' => 'Male']);
They would receive this success: