=====
CS 328 - Week 10 Lecture 2 - 2025-04-02
=====

=====
TODAY WE WILL
=====
*   announcements
*   attempted kinetic activity
*   quick aside: string concatenation in PHP (end how to get errors
    to your browser)
*   aside: variable interpolation in PHP strings
*   writing your own functions
*   whirlwind intro to using PHP and OCI to connect to the
    Oracle student database
*   prep for next class

=====
*   should be working on Homework 8!
    *   at-least-1st-attempts due by 11:59 pm on Friday, April 4

*   should be reading and working through the activities
    in zyBooks Chapter 5 - PHP Fundamentals

=====
SIDE NOTE: if you are considering taking Humboldt courses in SUMMER 2025
=====
*   registration for SUMMER 2025 opens for ***EVERYONE*** on APRIL 14!!!!

*   from:
    https://www.humboldt.edu/student-financial-services/summer-term-2025

    "For the 2025 Summer term, the university is guaranteeing 4 units,
    if enrolled in 6 or more units, will be covered for all continuing
    matriculated undergraduate students. This will cover 4 units of
    the tuition charge and does not include coverage of mandatory
    campus-based fees or the additional non-resident tuition if
    applicable."

    *   see the above link for more information!

=====
string concatenation in PHP
=====
*   you use a . operator instead of + !!!!!!!  <-- PHP got that from Perl!

    <p> <?= "a" . "b" . "c" ?> </p>
     |
     | when the PHP is executed, this becomes:
     v  
    <p> abc </p>

    *   see 328lect10-2.php

=====
to turn ON error messages for an individual PHP document
    on nrs-projects
=====
*   nrs-projects has PHP error messages turned off by default
    (that is, in the php.ini file for nrs-projects, there is a setting that
    keeps PHP error messages from being included in a PHP document's executed
    results that are sent to the client tier's browser)

    *   (it is not considered good practice to include them in a production
        setting...)

*   BUT, they can be very useful in debugging!
    SO -- happily, nrs-projects IS set up so that individual PHP documents
    can enable error messages to be included;

*   near the beginning of your PHP document,
    (I'd recommend your first regular PHP tag, placed in the head element,
    and I like to put it after the meta element)

    <?php
        ini_set('display_errors', 1);
	error_reporting(E_ALL);
    ?>

    *   now, PHP error messages should be enabled

    BUT NOTE!!!!
    *   certain PHP syntax errors still result in the PHP engine
        sending no result --
        (not unlike how a syntax error can keep a C++ compiler from
	giving you an executable result...)

        running your PHP from the nrs-projects command
	line will sometimes give you a parse-level error message:

	[nrs-projects]$ php desired_php.php

=====
variable interpolation in PHP
=====
*   WHEN you write a string in double-quotes,
    if there is a variable name in that string,
    that variable will be replaced by its value in the
    computed result
    ^
    |
    that's varible interpolation

*   if you don't want variable interpolation,
    you can write the string in single-quotes,
    and any $ is just considered a $ (not the
    start of a variable)

    <?php
        $looky = 13;
    ?>

    <p> <?= "what is this: $looky" ?> </p>  
     |
     | when the PHP is executed, this becomes:
     v  
    <p> what is this: 13 </p>
                      ^^
                      ||

    <p> <?= 'what is this: $looky' ?> </p> 
     |
     | when the PHP is executed, this becomes:
     v  
    <p> what is this: $looky </p>
                      ^^^^^^
                      ||||||
		      
*   what if you have a variable and you want to surround its
    value with NON-whitespace characters?

    in your double-quotes string, CURLY BRACES immediately
    before the $ and somewhere after 
    the variable name will make EXPLICIT
    where the variable name begins and ends

    <p> <?= "0{$looky}0" ?> </p>
     |
     | when the PHP is executed, this becomes:
     v
    <p> 0130 </p>
         ^^
	 ||

    *   see 328lect10-2.php

=====
how to write a function in PHP
=====

<?php
    /*===
        signature: desired_funct_name: desired_type desired_type --> ret_type
	purpose: expects description of expected arguments, returns
	    description of return value
    ===*/

    function desired_funct_name( $param1, $param2, ...)
    {
        statement;
	...
	statement;

        return; /* or */ return expr;
    }

*   you do not have to have a return statement --
    if you do not, the function simply ends when you
    reach the end of its body

*   but, like many other languages,
    if you execute a return statement,
    the function ends AT that point

*   see square.php
    and see how 328lect10-2.php uses:

    <?php
        require_once("square.php");
    ?>

    ...in its head element to put square function's definition there,

       and you can then call the square function as desired in PHP tags within its
       body

=====
using OCI to connect from PHP to Oracle
=====
*   there are MULTIPLE packages for allowing a PHP engine
    on an application tier to request actions from the data tier;

    we want to request actions from an Oracle databases,
    so we want to use one of the packages for that,

    and the one supported for the PHP engine on nrs-projects
    that can talk to the Oracle student database on campus
    is OCI - Oracle Call Interface

====
*   in OCI,
    you first need to establish a connection between
    the PHP engine and Oracle

    oci_connect is a function you can use for this.

    you call oci_connect with appropriate arguments,
    it returns a connection object that PHP on the application
    tier can use to request that SQL statements (and PL/SQL functions
    and procedures) be run for it on the data tier

*   (and because the number of connections to the Oracle db
    on campus is FINITE,
    
    class style is to explicitly CLOSE your connection,
    using:
    
    oci_close with your connection object as its argument:

    oci_close($conn);

    ...as soon as you are done with the connection!!!!!!!!!!!!!!!!

*   BUT -- say you have gotten a connection object using oci_connect.

    BEFORE you close it using oci_close -- what can you DO with the
    connection?

    ONE of SEVERAL possibilities:

    *   if the PHP document wants to ask the data tier/Oracle to
        execute a static query/select statement, it can do so as follows:

        (static? means it is not dynamic, it is the same hard-coded
        unchanging query each time -- as opposed to one that gets
        adapted or built based on user input, for example)

        *   use oci_parse to ask Oracle to set up a query and return
	    a statement object

            [when I checked
	    https://www.php.net/manual/en/function.oci-parse.php
	    after class, it calls it the statement identifier; hmm!]

            (not unlike a pre-compilation step, I think???)

        *   use oci_execute to ask Oracle to execute that statement

        *   use oci_fetch to get access to the next row in the result

            [when I checked
	    https://www.php.net/manual/en/function.oci-fetch.php
	    after class, it says it:

            "Fetches the next row from [an executed] query into internal
	    buffers accessible..." with a command such as oci_result]

            *   oci_fetch returns true if it succeeded in fetching a next row,
	        and false if there are no more rows to fetch

        *   and, if the oci_fetch succeeded, use oci_result to grab a
	    particular value from that row

            *   (and continue using oci_fetch and oci_result until you have
	        all the rows, or all the rows you want...)

        *   when done with the statement object,
            free it using oci_free_statement
	    *   from https://www.php.net/manual/en/function.oci-free-statement.php:

                "Frees resources associated with Oracle's cursor or statement"
            
        *   and when done with the connection object,
            use oci_close to close the connection!
	    ^^^^
	    |||| REMEMBER TO DO THIS!!!!!!!
  
    *   we ran out of time in this class,
        but because oci_fetch returns true if it succeeds in fetching a next
	row and returns false if it could not,

        a common pattern when asking that a query be executed that MIGHT select
	MULTIPLE rows is to use the call to oci_fetch as the bool
        expression in a while loop, to do something with each row selected:

        ...oci_connect...
        ...oci_parse...
        ...oci_execute...

        while (oci_fetch(...))
        {
	   ...
           ... oci_result ...
	   ... oci_result ...
	   ...
        }

        oci_free_statment(...);
        oci_close(...);