Skip to content

Instantly share code, notes, and snippets.

@arsenanai
Created July 9, 2026 11:48
Show Gist options
  • Select an option

  • Save arsenanai/f94a4151a32011e4983b883705daadc6 to your computer and use it in GitHub Desktop.

Select an option

Save arsenanai/f94a4151a32011e4983b883705daadc6 to your computer and use it in GitHub Desktop.
Rebilly coding exam answers — sandbox test files

Answers from Arsen Anay

Question 1: fetching DB results

fetchAll() loads everything into memory at once. If your table has millions of rows, PHP runs out of memory and you get the fatal error.

With fetch() in a loop you only keep one row in memory at a time. Stays low no matter how big the table gets.

$stmt = $pdo->prepare('SELECT * FROM largeTable');
$stmt->execute();


while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
        // manipulate the data here
}

Question 2: phone number formatting

Just loop through the string, keep the digits, check its 10 digits long, then format it with substring.

javascript

function formatPhoneNumber(phone, delimiter = '-') {
  const str = String(phone);
  let digits = '';

  for (let i = 0; i < str.length; i++) {
    const c = str[i];
    if (c >= '0' && c <= '9') {
      digits += c;
    }
  }

  if (digits.length !== 10) {
    throw new Error('Invalid phone number: expected 10 digits');
  }

  return digits.substring(0, 3) + delimiter + digits.substring(3, 6) + delimiter + digits.substring(6);
}

PHP

function formatPhoneNumber($phone, $delimiter = '-')
{
  $str = (string)$phone;
  $digits = '';

  for ($i = 0; $i < strlen($str); $i++) {
    $c = $str[$i];
    if ($c >= '0' && $c <= '9') {
      $digits .= $c;
    }
  }

  if (strlen($digits) !== 10) {
    throw new InvalidArgumentException('Expected 10 digits');
  }

    return substr($digits, 0, 3) . $delimiter . substr($digits, 3, 3) . $delimiter . substr($digits, 6);
}

Question 3: generating a hex color from a name

Take each character code, multiply by 31 and sum them up, turn the result into hex, grab the first 6 characters.

function getColorFromName(name) {
  let hash = 0;

  for (let i = 0; i < name.length; i++) {
    hash = hash * 31 + name.charCodeAt(i);
  }

  
  let hex = Math.abs(hash).toString(16);
  return '#' + hex.substring(0, 6).padStart(6, '0');
}

Question 4: Unit tests for FizzBuzz

Here are the PHPUnit tests for the FizzBuzz function.

class FizzBuzzTest extends PHPUnit\Framework\TestCase
{
    public function testRange(): void
    {
        $this->assertSame('12Fizz4Buzz', fizzBuzz(1, 5));
    }

    public function testFizz(): void
    {
        $this->assertEquals('Fizz', fizzBuzz(3, 3));
        $this->assertEquals('Fizz', fizzBuzz(9, 9));
    }

    public function testBuzz(): void
    {
        $this->assertSame('Buzz', fizzBuzz(5, 5));
    }

    public function testFizzBuzz(): void
    {
        $this->assertSame('FizzBuzz', fizzBuzz(15, 15));
    }


    public function testRegular(): void
    {
        $this->assertSame('7', fizzBuzz(7, 7));
    }

    public function testInvalid(): void
    {
        $this->expectException(InvalidArgumentException::class);
        fizzBuzz(10, 5);
    }
}

Question 5: refactoring the TypeScript todo app

Cleaned up the any types everywhere, added an interface, pulled the save logic out of the state mess.

interface TodoItem {
  id: number;
  text: string;
}

let items: TodoItem[] = JSON.parse(localStorage.getItem('items') || '[]');
const root = document.getElementById('app');

function save() {
  localStorage.setItem('items', JSON.stringify(items));
}

function render() {
  if (!root) return;

  root.innerHTML = '';
  const main = document.createElement('main');

  const listHtml = items
    .map((item) => `<li id="${item.id}">${item.text} <button data-remove>✘</button></li>`)
    .join('');

  main.innerHTML = `
    <form>
      <input placeholder="Todo…" />
    <button type="submit">Add</button>
    </form>
    <ul>${listHtml}</ul>
  `;

  const form = main.querySelector('form')!;
  const input = main.querySelector('input')!;

  form.onsubmit = (e: any) => {
    e.preventDefault();
    const text = (input.value || '').trim();
    if (!text) return;

    items = [...items, { id: Date.now(), text }];
    save();
    render();
    input.value = '';
  };

  main.onclick = (e: any) => {
    const btn = e.target as HTMLElement;
    if (!btn?.matches?.('[data-remove]')) return;

    const li = btn.closest('li');
    const id = li?.getAttribute('id');
    if (id) {
      items = items.filter((item) => item.id !== Number(id));
      save();
      render();
    }
  };

  root.appendChild(main);
}

// TODO: handle empty state and maybe add loading indicator
render();

Question 6: Refactoring PHP legacy classes

Replaced init() with __construct, made all properties private and typed, injected PDO instead of using the database singleton, and switched to prepared statements.

<?php

class Document 
{
    private string $name;
    private User $user;

    public function __construct(string $name, User $user) 
    {
        if (strlen($name) <= 5) {
            throw new InvalidArgumentException('Document name must be longer than 5 characters.');
        }
        $this->name = $name;
        $this->user = $user;
    }

    public function getName(): string 
    {
        return $this->name;
    }

    public function getUser(): User 
    {
        return $this->user;
    }

    public function getTitle(PDO $db): string 
    {
        $stmt = $db->prepare('SELECT title FROM document WHERE name = :name LIMIT 1');
        $stmt->execute(['name' => $this->name]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$row) {
            throw new RuntimeException("Document not found");
        }
        return $row['title'];
    }

    public static function getAllDocuments(): array 
    {
        // TODO: implement this
        return [];
    }
}

class User 
{
    private int $id;

    public function __construct(int $id) 
    {
        $this->id = $id;
    }

    public function getId(): int 
    {
        return $this->id;
    }

    public function makeNewDocument(string $name): Document 
    {
        if (strpos(strtolower($name), 'senior') === false) {
            throw new InvalidArgumentException('The name should contain "senior"');
        }

        return new Document($name, $this);
    }

    public function getMyDocuments(PDO $db): array 
    {
        $stmt = $db->prepare('SELECT * FROM document WHERE user_id = :user_id');
        $stmt->execute(['user_id' => $this->id]);

        $docs = [];
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $docs[] = new Document($row['name'], $this);
        }
        return $docs;
    }
}
{
"require-dev": {
"phpunit/phpunit": "^11.0"
}
}
<?xml version="1.0"?>
<phpunit>
<testsuite name="fizzbuzz">
<file>q4_fizzbuzz_test.php</file>
</testsuite>
</phpunit>
<?php
$pdo = new PDO('sqlite::memory:');
$pdo->exec('CREATE TABLE largeTable (id INTEGER, val TEXT)');
for ($i = 1; $i <= 8; $i++) {
$pdo->exec("INSERT INTO largeTable VALUES ($i, 'row_$i')");
}
$stmt = $pdo->prepare('SELECT * FROM largeTable');
$stmt->execute();
// $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
// var_dump($results);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "id: {$row['id']} - {$row['val']}\n";
}
<?php
function formatPhoneNumber($phone, $delimiter = '-')
{
$str = (string)$phone;
$digits = '';
for ($i = 0; $i < strlen($str); $i++) {
$c = $str[$i];
if ($c >= '0' && $c <= '9') {
$digits .= $c;
}
}
if (strlen($digits) !== 10) {
throw new InvalidArgumentException('Expected 10 digits');
}
return substr($digits, 0, 3) . $delimiter . substr($digits, 3, 3) . $delimiter . substr($digits, 6);
}
echo formatPhoneNumber('(123) 456-7890') . "\n";
echo formatPhoneNumber(1234567890) . "\n";
echo formatPhoneNumber('123.456.7890', '.') . "\n";
function getColorFromName(name) {
let hash = 0;
for (let i = 0; i < name.length; i++) {
hash = hash * 31 + name.charCodeAt(i);
}
let hex = Math.abs(hash).toString(16);
return '#' + hex.substring(0, 6).padStart(6, '0');
}
console.log(getColorFromName('Gulim Satayeva'));
console.log(getColorFromName('Omar Iliyas'));
console.log(getColorFromName('New York'));
<?php
function fizzBuzz($start = 1, $stop = 100)
{
$string = '';
if($stop < $start || $start < 0 || $stop < 0) {
throw new InvalidArgumentException;
}
for($i = $start; $i <= $stop; $i++) {
if($i % 3 == 0 && $i % 5 == 0) {
$string .= 'FizzBuzz';
continue;
}
if($i % 3 == 0) {
$string .= 'Fizz';
continue;
}
if ($i % 5 == 0) {
$string .= 'Buzz';
continue;
}
$string .= $i;
}
return $string;
}
<?php
require_once __DIR__ . '/q4_fizzbuzz.php';
class q4_fizzbuzz_test extends PHPUnit\Framework\TestCase
{
public function testRange(): void
{
$this->assertSame('12Fizz4Buzz', fizzBuzz(1, 5));
}
public function testFizz(): void
{
$this->assertEquals('Fizz', fizzBuzz(3, 3));
$this->assertEquals('Fizz', fizzBuzz(9, 9));
}
public function testBuzz(): void
{
$this->assertSame('Buzz', fizzBuzz(5, 5));
}
public function testFizzBuzz(): void
{
$this->assertSame('FizzBuzz', fizzBuzz(15, 15));
}
public function testRegular(): void
{
$this->assertSame('7', fizzBuzz(7, 7));
}
public function testInvalid(): void
{
$this->expectException(InvalidArgumentException::class);
fizzBuzz(10, 5);
}
}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>q5 todo</title>
</head>
<body>
<div id="app"></div>
<script src="q5_todo.js"></script>
</body>
</html>
"use strict";
let items = JSON.parse(localStorage.getItem('items') || '[]');
const root = document.getElementById('app');
function save() {
localStorage.setItem('items', JSON.stringify(items));
}
function render() {
if (!root)
return;
root.innerHTML = '';
const main = document.createElement('main');
const listHtml = items
.map((item) => `<li id="${item.id}">${item.text} <button data-remove>✘</button></li>`)
.join('');
main.innerHTML = `
<form>
<input placeholder="Todo…" />
<button type="submit">Add</button>
</form>
<ul>${listHtml}</ul>
`;
const form = main.querySelector('form');
const input = main.querySelector('input');
form.onsubmit = (e) => {
e.preventDefault();
const text = (input.value || '').trim();
if (!text)
return;
items = [...items, { id: Date.now(), text }];
save();
render();
input.value = '';
};
main.onclick = (e) => {
const btn = e.target;
if (!btn?.matches?.('[data-remove]'))
return;
const li = btn.closest('li');
const id = li?.getAttribute('id');
if (id) {
items = items.filter((item) => item.id !== Number(id));
save();
render();
}
};
root.appendChild(main);
}
// TODO: add edit / reorder functionality
render();
interface TodoItem {
id: number;
text: string;
}
let items: TodoItem[] = JSON.parse(localStorage.getItem('items') || '[]');
const root = document.getElementById('app');
function save() {
localStorage.setItem('items', JSON.stringify(items));
}
function render() {
if (!root) return;
root.innerHTML = '';
const main = document.createElement('main');
const listHtml = items
.map((item) => `<li id="${item.id}">${item.text} <button data-remove>✘</button></li>`)
.join('');
main.innerHTML = `
<form>
<input placeholder="Todo…" />
<button type="submit">Add</button>
</form>
<ul>${listHtml}</ul>
`;
const form = main.querySelector('form')!;
const input = main.querySelector('input')!;
form.onsubmit = (e: any) => {
e.preventDefault();
const text = (input.value || '').trim();
if (!text) return;
items = [...items, { id: Date.now(), text }];
save();
render();
input.value = '';
};
main.onclick = (e: any) => {
const btn = e.target as HTMLElement;
if (!btn?.matches?.('[data-remove]')) return;
const li = btn.closest('li');
const id = li?.getAttribute('id');
if (id) {
items = items.filter((item) => item.id !== Number(id));
save();
render();
}
};
root.appendChild(main);
}
// TODO: add edit / reorder functionality
render();
<?php
class Document
{
private string $name;
private User $user;
public function __construct(string $name, User $user)
{
if (strlen($name) <= 5) {
throw new InvalidArgumentException('Document name must be longer than 5 characters.');
}
$this->name = $name;
$this->user = $user;
}
public function getName(): string
{
return $this->name;
}
public function getUser(): User
{
return $this->user;
}
public function getTitle(PDO $db): string
{
$stmt = $db->prepare('SELECT title FROM document WHERE name = :name LIMIT 1');
$stmt->execute(['name' => $this->name]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$row) {
throw new RuntimeException("Document not found");
}
return $row['title'];
}
public static function getAllDocuments(): array
{
// TODO: implement this later
return [];
}
}
class User
{
private int $id;
public function __construct(int $id)
{
$this->id = $id;
}
public function getId(): int
{
return $this->id;
}
public function makeNewDocument(string $name): Document
{
if (strpos(strtolower($name), 'senior') === false) {
throw new InvalidArgumentException('The name should contain "senior"');
}
return new Document($name, $this);
}
public function getMyDocuments(PDO $db): array
{
$stmt = $db->prepare('SELECT * FROM document WHERE user_id = :user_id');
$stmt->execute(['user_id' => $this->id]);
$docs = [];
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$docs[] = new Document($row['name'], $this);
}
return $docs;
}
}
$user = new User(7);
$doc = $user->makeNewDocument('Senior Engineer');
echo $doc->getName() . "\n";
echo $doc->getUser()->getId() . "\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment