2082

BIT301 · TU past paper

Web Technology II 2082 question paper

The complete TU 2082 exam paper for Web Technology II (BIT301), all 12 questions with solved model answers written to the mark scheme.

Past Papers2082208120802079

Tap a question to open its answer.

  1. 110 marksLoosely typed language characteristicsAnswer

    Why is PHP a loosely typed language? How is the for loop different from the foreach loop? Write a PHP program to demonstrate the use of both loops.[10]

    PHP: Loosely Typed Language, for vs foreach Loops


    Part A: Why is PHP a Loosely Typed Language?

    PHP is called a loosely typed (or dynamically typed) language because:

    • Variables do not require explicit data type declaration
    • The data type of a variable is automatically determined at runtime based on the value assigned to it
    • The same variable can hold different types of values at different points in the program
    • PHP performs automatic type conversion (known as type juggling) when needed in expressions

    Example Illustrating Loose Typing:

    <?php
    $x = 10;        // $x is integer
    $x = "Hello";   // $x is now a string (no error)
    $x = 3.14;      // $x is now a float
    
    // Type juggling example
    $result = "5" + 10;   // PHP automatically converts "5" to integer
    echo $result;          // Output: 15
    ?>
    

    Contrast: In strongly typed languages like Java or C, you must declare int x = 10; and assigning a string to x later causes a compile-time error. PHP removes this restriction entirely.


    Part B: Difference Between for Loop and foreach Loop

    Featurefor Loopforeach Loop
    PurposeUsed when the number of iterations is known in advanceUsed to iterate over arrays or collections
    SyntaxRequires initialization, condition, and incrementRequires only the array and a loop variable
    Index ControlProgrammer manually manages the indexIndex/key is handled automatically
    Use CaseCounter-based or numeric repetition tasksTraversing all elements of an array
    RiskCan cause infinite loop if condition is wrongAlways terminates after the last element
    Key-Value AccessNot directly supportedSupports key => value pair access

    Part C: PHP Program Demonstrating Both Loops

    <?php
    
    // -----------------------------------------------
    // 1. Demonstrating for loop
    // -----------------------------------------------
    echo "Using for loop: ";
    
    for ($i = 1; $i <= 5; $i++) {
        echo "Number: " . $i . " ";
    }
    
    echo " ";
    
    // -----------------------------------------------
    // 2. Demonstrating foreach loop (indexed array)
    // -----------------------------------------------
    echo "Using foreach loop (indexed array): ";
    
    $fruits = array("Apple", "Banana", "Mango", "Orange", "Grapes");
    
    foreach ($fruits as $fruit) {
        echo "Fruit: " . $fruit . " ";
    }
    
    echo " ";
    
    // -----------------------------------------------
    // 3. Demonstrating foreach loop (associative array)
    // -----------------------------------------------
    echo "Using foreach loop (key => value): ";
    
    $marks = array("Math" => 90, "Science" => 85, "English" => 78);
    
    foreach ($marks as $subject => $score) {
        echo $subject . " : " . $score . " ";
    }
    
    ?>
    

    Expected Output:

    Using for loop:
    Number: 1
    Number: 2
    Number: 3
    Number: 4
    Number: 5
    
    Using foreach loop (indexed array):
    Fruit: Apple
    Fruit: Banana
    Fruit: Mango
    Fruit: Orange
    Fruit: Grapes
    
    Using foreach loop (key => value):
    Math : 90
    Science : 85
    English : 78
    

    Summary

    PointDetail
    Loosely TypedNo type declaration needed; type determined at runtime; type juggling occurs automatically
    for loopBest for counter-based iteration where the number of repetitions is known
    foreach loopBest for traversing arrays; supports both indexed and associative arrays cleanly

    PHP's loosely typed nature makes development faster and more flexible, while the foreach loop simplifies array traversal by eliminating the need for manual index management.

  2. 210 marksIndexed arrays and associative arraysAnswer

    How are indexed arrays different from associative arrays? Write a PHP program to demonstrate the conversion between array and variables.[10]

    Indexed Arrays vs Associative Arrays in PHP

    Difference Between Indexed Arrays and Associative Arrays

    FeatureIndexed ArrayAssociative Array
    Index TypeUses numeric indices (0, 1, 2, ...)Uses named string keys
    Key AssignmentKeys are assigned automaticallyKeys are assigned manually by the programmer
    Access MethodElements accessed by position numberElements accessed by meaningful key name
    Declaration$arr = array("a", "b", "c")$arr = array("key"=>"value")
    Use CaseOrdered list of itemsStoring related data with labels
    MemorySlightly more efficientSlightly more overhead due to string keys
    Example Key$arr[0], $arr[1]$arr["name"], $arr["age"]

    Conversion Between Array and Variables in PHP

    PHP provides two built-in functions for converting between arrays and variables:

    1. extract() - Array to Variables

    • Converts associative array keys into variable names
    • Syntax: extract($array)

    2. compact() - Variables to Array

    • Converts variables into an associative array
    • Syntax: compact("var1", "var2", ...)

    PHP Program

    <?php
    
    // ============================================
    // PART 1: Indexed Array vs Associative Array
    // ============================================
    
    echo "=== Indexed Array ===\n";
    
    // Indexed array - keys are automatically assigned (0, 1, 2...)
    $fruits = array("Apple", "Banana", "Mango", "Orange");
    
    // Accessing elements by numeric index
    echo "First fruit: " . $fruits[0] . "\n";
    echo "Second fruit: " . $fruits[1] . "\n";
    echo "Third fruit: " . $fruits[2] . "\n";
    
    // Loop through indexed array
    echo "All fruits: ";
    for ($i = 0; $i < count($fruits); $i++) {
        echo $fruits[$i] . " ";
    }
    echo "\n\n";
    
    echo "=== Associative Array ===\n";
    
    // Associative array - keys are named strings
    $student = array(
        "name"    => "Ram Sharma",
        "age"     => 21,
        "college" => "Tribhuvan University",
        "program" => "BSc CSIT"
    );
    
    // Accessing elements by key name
    echo "Name: "    . $student["name"]    . "\n";
    echo "Age: "     . $student["age"]     . "\n";
    echo "College: " . $student["college"] . "\n";
    echo "Program: " . $student["program"] . "\n";
    echo "\n";
    
    // ============================================
    // PART 2: Array to Variables using extract()
    // ============================================
    
    echo "=== Array to Variables using extract() ===\n";
    
    $person = array(
        "first_name" => "Sita",
        "last_name"  => "Rai",
        "city"       => "Kathmandu",
        "phone"      => "9841000000"
    );
    
    // Before extract - variables do not exist
    echo "Before extract():\n";
    echo isset($first_name) ? "first_name exists\n" : "first_name does NOT exist\n";
    
    // extract() converts array keys into variable names
    // and array values become variable values
    extract($person);
    
    // After extract - variables are now created
    echo "\nAfter extract():\n";
    echo "First Name : $first_name\n";
    echo "Last Name  : $last_name\n";
    echo "City       : $city\n";
    echo "Phone      : $phone\n";
    echo "\n";
    
    // ============================================
    // PART 3: Variables to Array using compact()
    // ============================================
    
    echo "=== Variables to Array using compact() ===\n";
    
    // Define individual variables
    $subject  = "PHP Programming";
    $semester = "Fifth";
    $marks    = 85;
    $grade    = "A";
    
    // compact() takes variable names as strings
    // and creates an associative array
    $result = compact("subject", "semester", "marks", "grade");
    
    // Display the resulting array
    echo "Array created using compact():\n";
    print_r($result);
    
    echo "\nAccessing individual elements:\n";
    echo "Subject  : " . $result["subject"]  . "\n";
    echo "Semester : " . $result["semester"] . "\n";
    echo "Marks    : " . $result["marks"]    . "\n";
    echo "Grade    : " . $result["grade"]    . "\n";
    echo "\n";
    
    // ============================================
    // PART 4: Round-trip demonstration
    // ============================================
    
    echo "=== Round-trip: Array -> Variables -> Array ===\n";
    
    // Start with an array
    $original = array(
        "country"  => "Nepal",
        "capital"  => "Kathmandu",
        "currency" => "Rupee"
    );
    
    echo "Original Array:\n";
    print_r($original);
    
    // Convert array to variables
    extract($original);
    echo "\nVariables after extract():\n";
    echo "country  = $country\n";
    echo "capital  = $capital\n";
    echo "currency = $currency\n";
    
    // Modify a variable
    $currency = "Nepalese Rupee (NPR)";
    
    // Convert variables back to array
    $updated = compact("country", "capital", "currency");
    echo "\nUpdated Array after compact():\n";
    print_r($updated);
    
    ?>
    

    Expected Output

    === Indexed Array ===
    First fruit: Apple
    Second fruit: Banana
    Third fruit: Mango
    All fruits: Apple Banana Mango Orange
    
    === Associative Array ===
    Name: Ram Sharma
    Age: 21
    College: Tribhuvan University
    Program: BSc CSIT
    
    === Array to Variables using extract() ===
    Before extract():
    first_name does NOT exist
    
    After extract():
    First Name : Sita
    Last Name  : Rai
    City       : Kathmandu
    Phone      : 9841000000
    
    === Variables to Array using compact() ===
    Array created using compact():
    Array
    (
        [subject] => PHP Programming
        [semester] => Fifth
        [marks] => 85
        [grade] => A
    )
    
    Accessing individual elements:
    Subject  : PHP Programming
    Semester : Fifth
    Marks    : 85
    Grade    : A
    
    === Round-trip: Array -> Variables -> Array ===
    Original Array:
    Array
    (
        [country] => Nepal
        [capital] => Kathmandu
        [currency] => Rupee
    )
    
    Variables after extract():
    country  = Nepal
    capital  = Kathmandu
    currency = Rupee
    
    Updated Array after compact():
    Array
    (
        [country] => Nepal
        [capital] => Kathmandu
        [currency] => Nepalese Rupee (NPR)
    )
    

    Conclusion

    An indexed array is keyed by integers starting at 0 and is read with a numeric subscript or a counting loop, while an associative array is keyed by meaningful strings and is read by name, which is what makes it the natural choice for record-like data. PHP moves between arrays and plain variables in both directions: extract() turns each key of an array into a variable of that name, and compact() collects named variables back into an associative array. The round-trip at the end of the program shows the pair working together, with the change made to $currency between the two calls appearing in the rebuilt array.

  3. 310 marksResponse headers and redirectsAnswer

    What are the response headers? Create a PHP login form that contains username, password and a login type field defined by dropdown menu. The login type options can be normal or admin. Now, write a function for implementing the login event. The event should be redirected to admin.php if the login credentials match and if the login type is admin otherwise it should be redirected to hello.php. Create a proper database connection based on your own assumption.[10]

    Response headers and a PHP login form

    What a response header is

    A response header is a line of metadata that the server sends back to the browser ahead of the response body, in the header block of the HTTP response. The body says what the page contains, the headers say how the browser should treat it: what media type it is, how long it may be cached, which cookie to store, whether the browser should go somewhere else instead. In PHP every response header is written with the header() function, and because headers travel before the body, header() must be called before a single byte of output (not even a blank line before <?php) has been sent.

    The headers a PHP programmer meets most often are these.

    HeaderWhat it does
    Content-TypeThe media type and charset of the body, for example text/html; charset=UTF-8
    LocationSends the browser to another URL, the header behind every PHP redirect
    Set-CookieStores a cookie in the browser, including the session cookie
    Cache-ControlStates whether and for how long the response may be cached
    Content-LengthSize of the body in bytes
    WWW-AuthenticateNames the authentication scheme the client must use
    ServerIdentifies the server software, usually best suppressed

    A redirect is therefore not a special PHP feature, it is just a Location response header plus a 302 status, and the exit after it stops the script from writing a body the browser would ignore.

    The database the program assumes

    The program assumes a MySQL database mydb with one table of accounts. The password column stores a hash, never the password itself, so it is sized for the 60 character bcrypt output that password_hash() produces, and the role of each account is stored in the table rather than trusted from the form.

    CREATE DATABASE mydb CHARACTER SET utf8mb4;
    
    USE mydb;
    
    CREATE TABLE users (
        id            INT AUTO_INCREMENT PRIMARY KEY,
        username      VARCHAR(50) NOT NULL UNIQUE,
        password_hash VARCHAR(255) NOT NULL,
        role          ENUM('normal', 'admin') NOT NULL DEFAULT 'normal'
    );
    

    Accounts are created by a small one off script, so that no plaintext password ever reaches the table:

    <?php
    require 'db.php';
    
    $stmt = db()->prepare('INSERT INTO users (username, password_hash, role) VALUES (?, ?, ?)');
    $name = 'admin1';
    $hash = password_hash('admin123', PASSWORD_DEFAULT);
    $role = 'admin';
    $stmt->bind_param('sss', $name, $hash, $role);
    $stmt->execute();
    

    The connection

    Keeping the connection in one function means the credentials appear once and every page opens the database the same way. mysqli_report() turns driver failures into exceptions so a mistyped query cannot pass silently, and set_charset() makes the connection agree with the table on utf8mb4.

    <?php
    // db.php
    declare(strict_types=1);
    
    function db(): mysqli
    {
        mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
        $conn = new mysqli('localhost', 'root', '', 'mydb');
        $conn->set_charset('utf8mb4');
        return $conn;
    }
    

    The login page

    login.php holds both the form and the function that handles the login event. The form posts back to the same file, handleLogin() runs only on a POST, and it returns an error string when the attempt fails so the page below can redisplay the form with a message.

    Three points in this function are what earn the marks. The username goes into the query as a bound parameter, so the value can never be read as SQL and injection is impossible. The submitted password is checked with password_verify() against the stored bcrypt hash, so the database holds nothing an attacker could reuse. And the requested login type is checked against the role stored in the row, because a dropdown lives in the browser and a user can post any value they like into it.

    <?php
    // login.php
    session_start();
    require 'db.php';
    
    function handleLogin(mysqli $conn): string
    {
        $username  = trim($_POST['username'] ?? '');
        $password  = $_POST['password'] ?? '';
        $loginType = $_POST['login_type'] ?? '';
    
        if ($username === '' || $password === '' || !in_array($loginType, ['normal', 'admin'], true)) {
            return 'Please fill in every field and choose a login type.';
        }
    
        $stmt = $conn->prepare('SELECT id, username, password_hash, role FROM users WHERE username = ? LIMIT 1');
        $stmt->bind_param('s', $username);
        $stmt->execute();
        $user = $stmt->get_result()->fetch_assoc();
        $stmt->close();
    
        // One message for both failures, so the page never reveals which usernames exist.
        if (!$user || !password_verify($password, $user['password_hash'])) {
            return 'Invalid username or password.';
        }
    
        if ($loginType === 'admin' && $user['role'] !== 'admin') {
            return 'This account is not an administrator account.';
        }
    
        // A fresh session id on every login defeats session fixation.
        session_regenerate_id(true);
        $_SESSION['user_id']  = (int) $user['id'];
        $_SESSION['username'] = $user['username'];
        $_SESSION['role']     = $user['role'];
    
        $destination = ($loginType === 'admin') ? 'admin.php' : 'hello.php';
        header("Location: $destination");
        exit;
    }
    
    $error = '';
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $error = handleLogin(db());
    }
    ?>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Login</title>
        <style>
            body { font-family: Arial, sans-serif; background: #f2f2f2; }
            .login-box { width: 350px; margin: 100px auto; padding: 30px; background: #fff;
                         border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,.2); }
            input, select, button { width: 100%; padding: 10px; margin: 8px 0 16px;
                                    box-sizing: border-box; border: 1px solid #ccc; border-radius: 4px; }
            button { background: #4CAF50; color: #fff; border: 0; cursor: pointer; }
            .error { color: #c00; }
        </style>
    </head>
    <body>
    <div class="login-box">
        <h2>Login</h2>
    
        <?php if ($error !== ''): ?>
            <p class="error"><?= htmlspecialchars($error, ENT_QUOTES, 'UTF-8') ?></p>
        <?php endif; ?>
    
        <form method="post" action="login.php">
            <label>Username</label>
            <input type="text" name="username"
                   value="<?= htmlspecialchars($_POST['username'] ?? '', ENT_QUOTES, 'UTF-8') ?>" required>
    
            <label>Password</label>
            <input type="password" name="password" required>
    
            <label>Login type</label>
            <select name="login_type">
                <option value="normal">Normal</option>
                <option value="admin">Admin</option>
            </select>
    
            <button type="submit">Login</button>
        </form>
    </div>
    </body>
    </html>
    

    The username is echoed back through htmlspecialchars() because it came from the request, and anything that came from the request may contain <script>. The password field is deliberately left empty on a failed attempt: a submitted password is never written back into the page.

    The two destination pages

    Each destination checks the session for itself. Without that check a user could simply type admin.php in the address bar and reach the page without logging in, because the redirect only tells the browser where to go, it does not protect the target.

    <?php
    // admin.php
    session_start();
    if (($_SESSION['role'] ?? '') !== 'admin') {
        header('Location: login.php');
        exit;
    }
    ?>
    <h2>Welcome, <?= htmlspecialchars($_SESSION['username'], ENT_QUOTES, 'UTF-8') ?>. You are signed in as an administrator.</h2>
    <a href="logout.php">Logout</a>
    
    <?php
    // hello.php
    session_start();
    if (!isset($_SESSION['user_id'])) {
        header('Location: login.php');
        exit;
    }
    ?>
    <h2>Hello, <?= htmlspecialchars($_SESSION['username'], ENT_QUOTES, 'UTF-8') ?>.</h2>
    <a href="logout.php">Logout</a>
    

    Logging out has to undo all three pieces of session state, the array, the cookie and the file on the server:

    <?php
    // logout.php
    session_start();
    $_SESSION = [];
    if (ini_get('session.use_cookies')) {
        $p = session_get_cookie_params();
        setcookie(session_name(), '', time() - 42000, $p['path'], $p['domain'], $p['secure'], $p['httponly']);
    }
    session_destroy();
    header('Location: login.php');
    exit;
    

    How the request flows

    browser posts username + password + login_type to login.php
            |
            v
    handleLogin() validates the fields
            |
            v
    prepared SELECT fetches the row for that username
            |
       row found and password_verify() passes?
            |                        |
           yes                       no
            |                        |
     role matches the        error string returned,
     requested type?         form redisplayed
            |
           yes
            |
     session_regenerate_id(true), session filled
            |
            v
     Location: admin.php   or   Location: hello.php
    

    In summary

    Response headers are the metadata the server sends ahead of the body, and header() is how PHP writes them, which is why the redirect in this program is nothing more than a Location header followed by exit. The login itself is safe because the username is bound into a prepared statement instead of pasted into the query text, the password is verified against a bcrypt hash rather than stored or compared in the clear, the session id is regenerated the moment the user is authenticated, the role comes from the database rather than from the dropdown, and every value printed back into the page passes through htmlspecialchars().

  4. 45 marksCharacter access in stringsAnswer

    Write a program that will read your name as input string. Access and display the individual characters in the name string. [5]

    A PHP string is an indexed sequence of characters, and a single character is reached with square brackets exactly as an array element is, so

  5. 55 marksCookie creation and handlingAnswer

    How can you handle cookies and sessions? Illustrate with examples. [5]

    Note: The reference notes did not contain material on this topic. The following answer is based on standard PHP web development curriculum as taught in BSc CSIT. --- A cookie is a small piece of data stored on the client's browser by the...

  6. 65 marksAnonymous classesAnswer

    What is anonymous class? Write a program to demonstrate the use of anonymous classes. [5]

    Anonymous classes in PHP

    An anonymous class is a class that is defined and instantiated in a single expression and is never given a name. PHP has supported them since version 7, written as new class { ... }. The value of the expression is an object, so the definition and the object creation happen together, which suits a case where an implementation is needed exactly once and a named class kept in its own file would only add noise.

    An anonymous class is an ordinary class in every other respect. It may accept constructor arguments, may extend one class, may implement any number of interfaces, and may use traits. Two anonymous classes written at two different places in the code are always distinct classes even when their bodies are identical, and because the class has no name it cannot be referred to, extended or reused elsewhere.

    The general form is:

    $object = new class ($constructorArguments) extends SomeClass implements SomeInterface {
        // properties and methods
    };
    

    A program that uses one

    <?php
    interface Logger
    {
        public function log(string $message): void;
    }
    
    class Report
    {
        private Logger $logger;
    
        public function __construct(Logger $logger)
        {
            $this->logger = $logger;
        }
    
        public function run(string $title): void
        {
            // the title may come from $_GET, so it is escaped before it is written to the
            // page, otherwise a title containing a script tag would run in the browser
            echo "<h3>" . htmlspecialchars($title, ENT_QUOTES, "UTF-8") . "</h3>";
            $this->logger->log("The report " . $title . " was generated.");
        }
    }
    
    // an anonymous class supplying a one off implementation of the Logger interface
    $report = new Report(new class implements Logger {
        public function log(string $message): void
        {
            echo "<p>LOG: " . htmlspecialchars($message, ENT_QUOTES, "UTF-8") . "</p>";
        }
    });
    
    $report->run("Monthly sales");
    
    // an anonymous class that takes a constructor argument of its own
    $counter = new class (10) {
        public function __construct(private int $value) {}
    
        public function next(): int
        {
            return ++$this->value;
        }
    };
    
    echo "<p>Next value: " . $counter->next() . "</p>";
    ?>
    

    The browser receives the heading Monthly sales, then the line LOG: The report Monthly sales was generated., and finally Next value: 11.

    What the example shows

    FeatureIn the example
    Defined and created togethernew class implements Logger { ... }
    Implements an interfaceSatisfies the Logger type that Report demands
    Takes constructor argumentsnew class (10) { ... } passes 10 to __construct()
    Has no nameNothing else in the program can refer to either class

    Anonymous classes are used for test doubles, for small strategy or callback objects, and for adapters that exist only to satisfy a type hint. A closure would serve when only one piece of behaviour is needed, but an anonymous class is the right tool when the interface being satisfied has several methods or when the object must carry state between calls.

  7. 75 marksHTTP authentication methodsAnswer

    What is HTTP authentication? How is it done? [5]

    HTTP Authentication is a built-in mechanism provided by the HTTP protocol that allows a web server to challenge a client (browser) for credentials (username and password) before granting access to a protected resource. It is defined in t...

  8. 85 marksError handling and error handlersAnswer

    What is the error handler? Write a program to demonstrate error handler function. [5]

    Error Handler in PHP

    Definition

    An error handler is a user-defined function that is called automatically whenever a PHP error occurs. Instead of displaying the default PHP error messages, a custom error handler allows the programmer to control how errors are handled, such as logging them, displaying custom messages, or redirecting the user.

    In PHP, the built-in function set_error_handler() is used to register a custom error handling function.


    Syntax

    set_error_handler("functionName");
    

    The custom error handler function must accept the following parameters:

    ParameterDescription
    $errnoError number/level
    $errstrError message
    $errfileFile where error occurred
    $errlineLine number where error occurred

    Program to Demonstrate Error Handler

    <?php
    
    // Step 1: Define the custom error handler function
    function myErrorHandler($errno, $errstr, $errfile, $errline) {
        echo "<b>Custom Error Handler Triggered!</b> ";
        echo "Error Number : " . $errno . " ";
        echo "Error Message: " . $errstr . " ";
        echo "Error File   : " . $errfile . " ";
        echo "Error Line   : " . $errline . " ";
        echo "<hr>";
    }
    
    // Step 2: Register the custom error handler
    set_error_handler("myErrorHandler");
    
    // Step 3: Trigger errors to test the handler
    
    // Triggering a user-defined notice
    trigger_error("This is a user notice!", E_USER_NOTICE);
    
    // Triggering a user-defined warning
    trigger_error("This is a user warning!", E_USER_WARNING);
    
    // Triggering a division by zero warning
    $a = 10;
    $b = 0;
    if ($b == 0) {
        trigger_error("Division by zero is not allowed!", E_USER_ERROR);
    }
    
    echo "Program continues after error handling.";
    
    ?>
    

    Output

    Custom Error Handler Triggered!
    Error Number : 1024
    Error Message: This is a user notice!
    Error File   : /path/to/file.php
    Error Line   : 20
    ---
    Custom Error Handler Triggered!
    Error Number : 512
    Error Message: This is a user warning!
    Error File   : /path/to/file.php
    Error Line   : 23
    ---
    Custom Error Handler Triggered!
    Error Number : 256
    Error Message: Division by zero is not allowed!
    Error File   : /path/to/file.php
    Error Line   : 28
    

    Key Points

    • set_error_handler() overrides PHP's default error handling.
    • trigger_error() is used to manually generate an error for testing.
    • Common error constants: E_USER_NOTICE, E_USER_WARNING, E_USER_ERROR.
    • Custom error handlers help in debugging, logging, and providing user-friendly error messages.
  9. 95 marksCSV file parsing and processingAnswer

    Write a program to parse a CSV file and display the content in the file. [5]

    Reading a CSV file and displaying its contents

    A CSV file stores a table as plain text: one record per line, with the fields of a record separated by commas and any field that itself contains a comma or a quote wrapped in double quotes. Because of that quoting rule a CSV line cannot be split reliably by hand, so PHP supplies fgetcsv(), which reads one record from an open file and returns its fields as an array with the quoting already resolved.

    Take the file data.csv:

    Name,Age,City
    Alice,23,Kathmandu
    Bob,25,Pokhara
    Charlie,22,Lalitpur
    

    The script reads the first record as the list of column names, pairs each later record with those names using array_combine(), and prints the result.

    <?php
    $filename = "data.csv";
    
    if (!is_readable($filename)) {
        exit("The CSV file could not be read.");
    }
    
    $handle = fopen($filename, "r");
    if ($handle === false) {
        exit("Unable to open the CSV file.");
    }
    
    $header = fgetcsv($handle, 0, ",");
    if ($header === false) {
        fclose($handle);
        exit("The CSV file is empty.");
    }
    
    echo "<table border='1'><tr>";
    foreach ($header as $column) {
        // file contents are untrusted, so they are escaped before reaching the page,
        // otherwise a field containing markup would be interpreted by the browser
        echo "<th>" . htmlspecialchars((string) $column, ENT_QUOTES, "UTF-8") . "</th>";
    }
    echo "</tr>";
    
    $count = 0;
    
    while (($row = fgetcsv($handle, 0, ",")) !== false) {
    
        if ($row === array(null)) {              // ignore a blank line
            continue;
        }
    
        if (count($row) !== count($header)) {    // a malformed record, report and skip it
            echo "<tr><td colspan='" . count($header) . "'>Skipped a record with the wrong number of fields.</td></tr>";
            continue;
        }
    
        $record = array_combine($header, $row);  // field name to field value
    
        echo "<tr>";
        foreach ($record as $value) {
            echo "<td>" . htmlspecialchars((string) $value, ENT_QUOTES, "UTF-8") . "</td>";
        }
        echo "</tr>";
    
        $count++;
    }
    
    echo "</table>";
    fclose($handle);
    
    echo "<p>Total records read: " . $count . "</p>";
    ?>
    

    What the page shows

    NameAgeCity
    Alice23Kathmandu
    Bob25Pokhara
    Charlie22Lalitpur

    followed by the line Total records read: 3.

    Functions used

    FunctionPurpose
    fopen($file, "r")Opens the file for reading and returns a handle
    fgetcsv($handle, 0, ",")Reads the next record and returns its fields as an array
    array_combine($keys, $values)Builds an associative record from the header names and the field values
    fclose($handle)Closes the file when the loop ends
    str_getcsv($line)Parses a single CSV line already held in a string

    Because $record is keyed by column name, a particular field can be printed directly, for example htmlspecialchars($record["City"], ENT_QUOTES, "UTF-8"), without depending on the position of that column in the file. That makes the script survive a reordering of the columns, which a program indexing by $row[2] would not.

    Two points decide whether such a script is correct in practice. The record must be read with fgetcsv() or str_getcsv() rather than explode(",", $line), because the quoting rule means a comma inside a quoted field is data and not a separator. And every value taken from the file must pass through htmlspecialchars() before it is echoed, since the file is input from outside the program and an unescaped field is a stored cross site scripting hole in the page that displays it.

  10. 105 marksData deletion from tablesAnswer

    Consider you have student records in a database table. Now create a PHP page with delete button action and a text field. The button should delete a record if it matches the name of the student entered in the text field. Use your own assumption for the database table. [5]

    The page works against a database school holding one table of students. Nothing about the design is unusual: a surrogate key, the student name, and two descriptive columns. id name age address ------------------------ 1 Ram Sharma 20 Kat...

  11. 115 marksGET versus POST comparisonAnswer

    Differentiate GET method from POST method with examples. [5]

    GET and POST are two fundamental HTTP methods used to send requests from a client (browser) to a server. They differ in how data is transmitted and their intended use cases. --- Feature GET Method POST Method --------- Data Transmission ...

  12. 125 marksClass and object definitionAnswer

    Write a program to create a class Employee with some attributes and methods. Create an object of the class and display some output using any method in the class. [5]

    An Employee class in PHP

    A class is the blueprint that describes what an employee record holds and what can be done with it, and an object is one concrete employee built from that blueprint. In PHP the properties are declared with a visibility keyword, the constructor is the magic method __construct(), and inside any method the current object is referred to as $this, with -> used to reach a property or call a method.

    <?php
    class Employee
    {
        private int    $id;
        private string $name;
        private string $department;
        private float  $salary;      // monthly salary
    
        public function __construct(int $id, string $name, string $department, float $salary)
        {
            $this->id         = $id;
            $this->name       = $name;
            $this->department = $department;
            $this->salary     = $salary;
        }
    
        public function getName(): string
        {
            return $this->name;
        }
    
        public function annualSalary(): float
        {
            return $this->salary * 12;
        }
    
        public function giveRaise(float $percent): void
        {
            $this->salary += ($this->salary * $percent) / 100;
        }
    
        public function display(): string
        {
            // the name and department are stored values that end up inside an HTML page,
            // so they are escaped here, since a value held in the database may contain
            // characters such as < or & that would otherwise be read as markup
            $safeName = htmlspecialchars($this->name, ENT_QUOTES, "UTF-8");
            $safeDept = htmlspecialchars($this->department, ENT_QUOTES, "UTF-8");
    
            return "<p>Employee ID: " . $this->id . " "
                 . "Name: " . $safeName . " "
                 . "Department: " . $safeDept . " "
                 . "Monthly salary: Rs. " . number_format($this->salary, 2) . "</p>";
        }
    }
    
    // creating an object of the class
    $emp = new Employee(101, "Ram Sharma", "IT", 50000);
    
    echo $emp->display();
    echo "<p>Annual salary: Rs. " . number_format($emp->annualSalary(), 2) . "</p>";
    
    $emp->giveRaise(10);
    echo "<p>After a 10 percent raise:</p>";
    echo $emp->display();
    ?>
    

    The page produced is:

    Employee ID: 101
    Name: Ram Sharma
    Department: IT
    Monthly salary: Rs. 50,000.00
    
    Annual salary: Rs. 600,000.00
    
    After a 10 percent raise:
    Employee ID: 101
    Name: Ram Sharma
    Department: IT
    Monthly salary: Rs. 55,000.00
    

    The parts of the class

    PartRole
    class Employee { ... }Declares the blueprint
    private int $id and the other threeThe attributes, hidden from outside code
    __construct()Runs automatically at new and fills the attributes
    $thisThe object the method is currently working on
    annualSalary(), giveRaise(), display()The methods, the behaviour of the object
    new Employee(101, "Ram Sharma", "IT", 50000)Creates one object from the blueprint

    Declaring the attributes private is what makes giveRaise() worth writing: outside code cannot reach in and set an arbitrary salary, it must go through a method that applies the rule. PHP 8 allows the same class to be written more briefly with constructor property promotion, where public function __construct(private int $id, private string $name) declares and assigns the properties in one line.