···11+<?php
22+33+declare(strict_types=1);
44+55+class Proverb
66+{
77+ public function recite(array $pieces): array
88+ {
99+ $output = [];
1010+1111+ for ($i = 0; $i < count($pieces); $i++) {
1212+ if ($i == count($pieces) - 1 || count($pieces) == 1) {
1313+ $output[] = "And all for the want of a {$pieces[0]}.";
1414+ } else {
1515+ $output[] = "For want of a {$pieces[$i]} the {$pieces[$i + 1]} was lost.";
1616+ }
1717+ }
1818+1919+ return $output;
2020+ }
2121+}
+101
php/proverb/ProverbTest.php
···11+<?php
22+33+/*
44+ * By adding type hints and enabling strict type checking, code can become
55+ * easier to read, self-documenting and reduce the number of potential bugs.
66+ * By default, type declarations are non-strict, which means they will attempt
77+ * to change the original type to match the type specified by the
88+ * type-declaration.
99+ *
1010+ * In other words, if you pass a string to a function requiring a float,
1111+ * it will attempt to convert the string value to a float.
1212+ *
1313+ * To enable strict mode, a single declare directive must be placed at the top
1414+ * of the file.
1515+ * This means that the strictness of typing is configured on a per-file basis.
1616+ * This directive not only affects the type declarations of parameters, but also
1717+ * a function's return type.
1818+ *
1919+ * For more info review the Concept on strict type checking in the PHP track
2020+ * <link>.
2121+ *
2222+ * To disable strict typing, comment out the directive below.
2323+ */
2424+2525+declare(strict_types=1);
2626+2727+use PHPUnit\Framework\TestCase;
2828+2929+class ProverbTest extends TestCase
3030+{
3131+ private Proverb $proverb;
3232+3333+ public static function setUpBeforeClass(): void
3434+ {
3535+ require_once 'Proverb.php';
3636+ }
3737+3838+ public function setUp(): void
3939+ {
4040+ $this->proverb = new Proverb();
4141+ }
4242+4343+ public function testNoVerses(): void
4444+ {
4545+ $pieces = [];
4646+ $expected = [];
4747+ $this->assertEquals($expected, $this->proverb->recite($pieces));
4848+ }
4949+5050+ public function testOneVerse(): void
5151+ {
5252+ $pieces = ['nail'];
5353+ $expected = ['And all for the want of a nail.'];
5454+ $this->assertEquals($expected, $this->proverb->recite($pieces));
5555+ }
5656+5757+ public function testTwoVerses(): void
5858+ {
5959+ $pieces = ['nail', 'shoe'];
6060+ $expected = ['For want of a nail the shoe was lost.', 'And all for the want of a nail.'];
6161+ $this->assertEquals($expected, $this->proverb->recite($pieces));
6262+ }
6363+6464+ public function testThreeVerses(): void
6565+ {
6666+ $pieces = ['nail', 'shoe', 'horse'];
6767+ $expected = [
6868+ 'For want of a nail the shoe was lost.',
6969+ 'For want of a shoe the horse was lost.',
7070+ 'And all for the want of a nail.'
7171+ ];
7272+ $this->assertEquals($expected, $this->proverb->recite($pieces));
7373+ }
7474+7575+ public function testFullProverb(): void
7676+ {
7777+ $pieces = ['nail', 'shoe', 'horse', 'rider', 'message', 'battle', 'kingdom'];
7878+ $expected = [
7979+ 'For want of a nail the shoe was lost.',
8080+ 'For want of a shoe the horse was lost.',
8181+ 'For want of a horse the rider was lost.',
8282+ 'For want of a rider the message was lost.',
8383+ 'For want of a message the battle was lost.',
8484+ 'For want of a battle the kingdom was lost.',
8585+ 'And all for the want of a nail.'
8686+ ];
8787+ $this->assertEquals($expected, $this->proverb->recite($pieces));
8888+ }
8989+9090+ public function testFourModernizedVerses(): void
9191+ {
9292+ $pieces = ['pin', 'gun', 'soldier', 'battle'];
9393+ $expected = [
9494+ 'For want of a pin the gun was lost.',
9595+ 'For want of a gun the soldier was lost.',
9696+ 'For want of a soldier the battle was lost.',
9797+ 'And all for the want of a pin.'
9898+ ];
9999+ $this->assertEquals($expected, $this->proverb->recite($pieces));
100100+ }
101101+}
+28
php/proverb/README.md
···11+# Proverb
22+33+Welcome to Proverb on Exercism's PHP Track.
44+If you need help running the tests or submitting your code, check out `HELP.md`.
55+66+## Instructions
77+88+For want of a horseshoe nail, a kingdom was lost, or so the saying goes.
99+1010+Given a list of inputs, generate the relevant proverb. For example, given the list `["nail", "shoe", "horse", "rider", "message", "battle", "kingdom"]`, you will output the full text of this proverbial rhyme:
1111+1212+```text
1313+For want of a nail the shoe was lost.
1414+For want of a shoe the horse was lost.
1515+For want of a horse the rider was lost.
1616+For want of a rider the message was lost.
1717+For want of a message the battle was lost.
1818+For want of a battle the kingdom was lost.
1919+And all for the want of a nail.
2020+```
2121+2222+Note that the list of inputs may vary; your solution should be able to handle lists of arbitrary length and content. **No line of the output text should be a static**, unchanging string; all should vary according to the input given.
2323+2424+## Source
2525+2626+### Created by
2727+2828+- @MichaelBunker