13. PHP 7.4.2, Bootstrap 4.3.1 : Laravel 6.12 CRUD tutorial

2020.02.17 Tested on newest Windows 10 64 bit, XAMPP – works !

http://localhost:8083/laravel6/public/shows/create
http://localhost:8083/laravel6/public/shows/ – here are del and edit buttons
http://localhost:8083/laravel6/public/shows/1/edit

https://appdividend.com/2019/09/12/laravel-6-crud-example-laravel-6-tutorial-for-beginners/ 2019.12.10 by Krunal

https://github.com/KrunalLathiya/Laravel6CRUDExample

http://dev1:8083/fwphp/glomodul/blog/?i/read_post/id/43#crequest is URL to show this article in my Blog (Msg module).

 

1. MySQL DB   2. M   3. C requeest   4. Bootstrap 4

5. CreRequest   6. validateSaveResponse

7. RvDisplayresponse   8. CUD   9. D

Install Laravel 6.12

1. MySQL DB   2. M   3. C requeest   4. Bootstrap 4

5. CreRequest   6. validateSaveResponse

7. RvDisplayresponse   8. CUD   9. D

Install Laravel 6.12

For some reason WordPress editor changes pasted text to uppercase !! eg :
composer create-project –prefer-dist laravel/laravel laravel6

~ 130 MB – one of reasons why I do not like such developing SW (included is Oracle Forms). If error – how debug 130 MB ?
B12phpfw has 20-30 kB code to debug (few hundert lines) using own debugging and Xdebug which both work excellent.
If there were somebody who guaranties support (for many years) then huge developing SW would be better. Stories about security… are not true – we only need good help about implement security and some features (which is difficult to find).

cd J:\xampp\htdocs\laravel6\
install the frontend dependencies :

npm install

Step 1. Configure MySQL DB

Values inside .env file are loaded inside the files from the config directory.

J:\xampp\htdocs\laravel6\.env file

Where J:\xampp\htdocs\laravel6\ is root of our laravel project.

If you make changes to .env file then don’t forget to restart server ( if you are using laravel dev server). If you are using virtual host and changes don’t seem to take effect then run :

cd J:\xampp\htdocs\laravel6\

php artisan config:clear

(This command will clear the configuration cache) in your terminal.

Laravel always ships with the migration files, so you can generate DB tables so :

php artisan migrate

migrations table created successfully. Laravel comes with three migrations which are used for authentication. Their file names are prepended with a timestamp :

Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (0.48 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (0.44 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (0.27 seconds)

select * from information_schema.tables where table_schema = ‘z_laravel6’ and table_name = ‘migrations’ and table_type = ‘BASE TABLE’

Step 2. M – create model and migration files

Database migration is used to save details about DB table, so you don’t have to manually generate all of the tables by going to the database interface or phpmyadmin or …
We can develop migrations using artisan with ‘make: migration’ command.
Type the following command to create a model and migration files.

cd J:\xampp\htdocs\laravel6\

php artisan make:model Show -m

It will create migration files inside database/migrations directory J:\xampp\htdocs\laravel6\database\migrations\ :

  1. J:\xampp\htdocs\laravel6\database\migrations\Show.php file – model name has to be singular
  2. [timestamp]_create_shows_table.php migration file – migration name should be plural to automatically find table name.

//J:\xampp\htdocs\laravel6\database\migrations\2020_02_17_074520_create_shows_table.php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateShowsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     *
     * Create table in DB using the following command.
     *    php artisan migrate
     * execute up() function ee run all migrations and create defined tbls (incremental changes).
     *
     * To reverse the migrations :
     *    php artisan migrate:rollback which will execute the down() function.
     *
     */
    public function up()
    {
        Schema::create('shows', function (Blueprint $table) {
           $table->bigIncrements('id');        //**php artisan make:model Show -m created**
              $table->string('show_name');   //**I added**
              $table->string('genre');
              $table->float('imdb_rating');
              $table->string('lead_actor');
           $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('shows');
    }
}

If you want to create the migration but have a different table name in mind, then you can explicitly define a table name with ‘create‘ flag.

  1. up() function is used for creating/updating tables, columns, and indexes Inside up() function, We have the Schema: create(‘table_name,’ callback) method which will be used for creating the new table.
    1. Inside a callback, we have $table->bigIncrements(‘id’) which will create auto_increment integer column with the primary key and argument ‘id’ is the name of a column.
    2. Second is $table->timestamps() which will create the two timestamp columns created_at and updated_at.
  2. down() function is used for reversing an operation done by up() method
       $table->bigIncrements('id');        //**php artisan make:model Show -m created**       
          $table->string('show_name');   //**I added 4 columns**        
          $table->string('genre');      
          $table->float('imdb_rating');          
          $table->string('lead_actor');            
       $table->timestamps();  //**php artisan make:model Show -m created**          

Create table in DB using the following command :

php artisan migrate

which will execute up() function ee run all migrations and create defined tbls (incremental changes).

To reverse the migrations :

php artisan migrate:rollback

which will execute down() function.

Now, add the fillable property inside file :

J:\xampp\htdocs\laravel6\app\Show.php

// J:\xampp\htdocs\laravel6\app\Show.php
namespace App;
use Illuminate\Database\Eloquent\Model;

/*
* We can specify all the properties to modify the behavior of the model.
* We can write a $table property which is used to determine a name of the table that this model will interact with in the future operations.
* By default, It will define a table name as the plural of the model name, e.g., shows table for Show model and users table for User model.
* When you don't need to use timestamps on your table, then you will also have to specify the $timestamps property and set it to false value in your Model because Laravel expects your table to have the created_at and updated_at timestamp columns.
*/
class Show extends Model
{
   protected $fillable = [
      'show_name', 'genre', 'imdb_rating', 'lead_actor'
   ];
}

Step 3. C – Create routes and controller

First, create the ShowController using the following command.

php artisan make:controller ShowController –resource

Note that we have also added the — resource flag which will define six methods inside the ShowController namely:

  1. Index (used for displaying a list of Shows)
  2. Create (will show the view with a form for creating a Show)
  3. Store (used for creating a Show inside the database. Note: create method submits to store method)
  4. Show (will display a specified Show)
  5. Edit (will show the form for editing a Show. Form will be filled with the existing Show data)
  6. Update (Used for updating a Show inside the database. Note: edit submits to update method)
  7. Destroy (used for deleting a specified Show)

J:\xampp\htdocs\laravel6\routes\web.php

add Route::resource… line of code :

// ShowController.php
Route::get('/', function () {
    return view('welcome');
});

Route::resource('shows', 'ShowController');

We can pass dynamic parameters with {} brackets, and you might have noticed that show, update, and destroy has the same url but different methods, so its legit.

Just like resource flag, laravel has a method called resource() that will generate all the above routes. You can also use that method instead of specifying them individually like above.

Actually, by adding Route::resource… line, we have registered multiple routes for our application. We can check it so :

php artisan route:list

Domain Method URI Name Action Middleware
GET/HEAD / Closure web
GET/HEAD api/user Closure api,auth:api
GET/HEAD shows shows.index App\Http\Controllers\ShowController@index web
POST shows shows.store App\Http\Controllers\ShowController@store web
GET/HEAD shows/create shows.create App\Http\Controllers\ShowController@create web
GET/HEAD shows/{show} shows.show App\Http\Controllers\ShowController@show web
PUT/PATCH shows/{show} shows.update App\Http\Controllers\ShowController@update web
DELETE shows/{show} shows.destroy App\Http\Controllers\ShowController@destroy web
GET/HEAD shows/{show}/edit shows.edit App\Http\Controllers\ShowController@edit web

Step 4. Configure Bootstrap 4

Right now (2019.12.10), there are some issues, or somehow I do not see any code inside the public >> css >> app.css file. I have already compiled the CSS and JS file by the

npm run dev

command, but still, the app.css file is empty.

One possible solution is to copy code of previous version’s Laravel’s app.css file and paste it here :

J:\xampp\htdocs\laravel6\public\css\ap.css

Link of the previous css file is :
https://raw.githubusercontent.com/KrunalLathiya/Laravel58CRUD/master/public/css/app.css

Second possible solution is this. This new scaffolding is only available in Laravel 6 and not in the earlier versions like Laravel 5.8 or 5.7.

While Laravel 6 does not dictate which JavaScript or CSS pre-processors you use, it does provide the essential starting point using Bootstrap and Vue that will be helpful for many projects.

By default, the Laravel uses the NPM to install both of these frontend packages.

Bootstrap and Vue scaffolding provided by Laravel is located in the laravel/ui Composer package, which you can install using Composer so :

composer require laravel/ui –dev

Once laravel/ui package has been installed, and you may install the frontend scaffolding using the ui Artisan command:

// Generate basic scaffolding…
php artisan ui vue
php artisan ui react

// Generate login / registration scaffolding…
php artisan ui vue –auth
php artisan ui react –auth

Step 5. Create request (form to insert show tbl row)

Create the views.

http://localhost:8083/laravel6/public/shows/create

Inside the J:\xampp\htdocs\laravel6\resources\views folder where is only welcome.blade.php , create view files :

  1. C create.blade.php
  2. U edit.blade.php
  3. R index.blade.php Inside the views folder, we also need to create the layout file. So create a file inside the views folder called

    layout.blade.php :

    our main template file, and all the other view files will extend this layout.blade.php file.

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Laravel 6 CRUD Example</title>
    <link href="{{ asset('css/app.css') }}" rel="stylesheet" type="text/css" />
    </head>
    <body>
    <div class="container">
    @yield('content')
    </div>
    <script src="{{ asset('js/app.js') }}" type="text/js"></script>
    </body>
    </html>

    Here, we have already included the Bootstrap 4 by adding the app.css.

create.blade.php :

@extends('layout')

@section('content')
<style>
  .uper {
    margin-top: 40px;
  }
</style>
<div class="card uper">
  <div class="card-header">
    Add Shows
  </div>
  <div class="card-body">
    @if ($errors->any())
      <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
              <li>{{ $error }}</li>
            @endforeach
        </ul>
      </div><br />
    @endif
      <form method="post" action="{{ route('shows.store') }}">
          <div class="form-group">
              @csrf
              <label for="name">Show Name:</label>
              <input type="text" class="form-control" name="show_name"/>
          </div>
          <div class="form-group">
              <label for="price">Show Genre :</label>
              <input type="text" class="form-control" name="genre"/>
          </div>
          <div class="form-group">
              <label for="price">Show IMDB Rating :</label>
              <input type="text" class="form-control" name="imdb_rating"/>
          </div>
          <div class="form-group">
              <label for="quantity">Show Lead Actor :</label>
              <input type="text" class="form-control" name="lead_actor"/>
          </div>
          <button type="submit" class="btn btn-primary">Create Show</button>
      </form>
  </div>
</div>
@endsection

Open ShowController.php file, and on the create() function, we need to return the view, and that is a create.blade.php file.

// ShowController.php

public function create()
{
   return view('create'); // create.blade.php file
}

Go to a http://localhost:8000/books/create or http://laravel6.test/shows/create

http://localhost:8083/laravel6/public/shows/create

You will see form “Create show”.
Add Shows Show Name: Show Genre : Show IMDB Rating : Show Lead Actor : Create show button

Step 6. Add Laravel Validation rules and save data

First step inside the ShowController.php is that import namespace of Show model inside the ShowController.php file.


// ShowController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Show; // import namespace of Show model 

Write following code inside ShowController.php file’s store() function.

public function store(Request $request)
{
        $validatedData = $request->validate([
            // check for all four fields of the form
            // If incoming data fail any of the rules, then it will directly go to the form with the error messages
            // $request object parameter will be used to access form data
            'show_name' => 'required|max:255',
            'genre' => 'required|max:255',
            'imdb_rating' => 'required|numeric',
            'lead_actor' => 'required|max:255',
        ]);

        $show = Show::create($validatedData);

        return redirect('/shows')->with('success', 'Show is successfully saved');
 }

The first thing you want to do is validate a form of data.
We can use a $request->validate() function for validation, which will receive the array of validation rules.
Validation rules is an associative array.
Key will be the field_name and value with being the validation rules.

The second parameter is the optional array for custom validation messages.
Rules are separated with pipe sign “|.” We are using the most basic validation rules https://laravel.com/docs/5.8/validation#available-validation-rules .

First is “required,” which means the field_name should not be empty. (“nullable” rule is vice versa), “string” means it should be the string value, “min” is the limit of minimum characters for a string in an input field and “max” is the maximum characters. “unique:table, column” with see if the same value does not exists in the database (comes handy for storing emails or any other unique data).

If the validation fails, then it will redirect us back. After the validation, we are creating a new book and save that book in the database.
We need to loop through that error messages inside the create.blade.php file which we have already done it.

If you leave all the form fields empty, then you will find an error message at page top.

Now, if you fill the form fields correctly, then it will create a new row in the database.

Step 7. V – display response

Display the data.

http://localhost:8083/laravel6/public/shows/

Write the ShowController’s index function to return an index view with data fetched from a database. Write the following code inside the index() function.

// ShowController.php

public function index()
{
     $shows = Show::all();

     return view('index', compact('shows'));
}

Create a file inside the views folder :

index.blade.php

@extends('layout')

@section('content')
<style>
  .uper {
    margin-top: 40px;
  }
</style>
<div class="uper">
  @if(session()->get('success'))
    <div class="alert alert-success">
      {{ session()->get('success') }}  
    </div><br />
  @endif
  <table class="table table-striped">
    <thead>
        <tr>
          <td>ID</td>
          <td>Show Name</td>
          <td>Show Genre</td>
          <td>Show IMDB Rating</td>
          <td>Lead Actor</td>
          <td colspan="2">Action</td>
        </tr>
    </thead>
    <tbody>
        @foreach($shows as $show)
        <tr>
            <td>{{$show->id}}</td>
            <td>{{$show->show_name}}</td>
            <td>{{$show->genre}}</td>
            <td>{{number_format($show->imdb_rating,2)}}</td>
            <td>{{$show->lead_actor}}</td>
            <td><a href="{{ route('shows.edit', $show->id)}}" class="btn btn-primary">Edit</a></td>
            <td>
                <form action="{{ route('shows.destroy', $show->id)}}" method="post">
                  @csrf
                  @method('DELETE')
                  <button class="btn btn-danger" type="submit">Delete</button>
                </form>
            </td>
        </tr>
        @endforeach
    </tbody>
  </table>
<div>
@endsection

We have used the PHP number_format() function to print the IMDB Rating float value.

Here, we have looped through the show’s array and display the data in the table format.

Also, we have added two buttons for edit and delete operation.

Step 8. CUD

Create Edit and Update Operation.
Add following code inside ShowController.php edit function :

// ShowController.php

public function edit($id)
{
     $show = Show::findOrFail($id);

     return view('edit', compact('show'));
}

Create new file inside the views folder

edit.blade.php

@extends('layout')

@section('content')
<style>
  .uper {
    margin-top: 40px;
  }
</style>
<div class="card uper">
  <div class="card-header">
    Update Shows
  </div>
  <div class="card-body">
    @if ($errors->any())
      <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
              <li>{{ $error }}</li>
            @endforeach
        </ul>
      </div><br />
    @endif
    <form method="post" action="{{ route('shows.update', $show->id) }}">
          <div class="form-group">
              @csrf
              @method('PATCH')
              <label for="name">Show Name:</label>
              <input type="text" class="form-control" name="show_name" value="{{ $show->show_name }}"/>
          </div>
          <div class="form-group">
              <label for="price">Show Genre :</label>
              <input type="text" class="form-control" name="genre" value="{{ $show->genre }}"/>
          </div>
          <div class="form-group">
              <label for="price">Show IMDB Rating :</label>
              <input type="text" class="form-control" name="imdb_rating" value="{{ number_format($show->imdb_rating, 2) }}"/>
          </div>
          <div class="form-group">
              <label for="quantity">Show Lead Actor :</label>
              <input type="text" class="form-control" name="lead_actor" value="{{ $show->lead_actor }}"/>
          </div>
          <button type="submit" class="btn btn-primary">Update Show</button>
      </form>
  </div>
</div>
@endsection

In this file, you can show the values of the particular row using its unique id inside the form fields.

So, when you hit this URL: http://localhost:8000/shows/1/edit or http://laravel6.test/shows/1/edit, you will see row edit form.

Create Edit and Update Operation

Add following code inside ShowController update() function.

// ShowController.php

public function update(Request $request, $id)
{
        $validatedData = $request->validate([
            'show_name' => 'required|max:255',
            'genre' => 'required|max:255',
            'imdb_rating' => 'required|numeric',
            'lead_actor' => 'required|max:255',
        ]);
        Show::whereId($id)->update($validatedData);

        return redirect('/shows')->with('success', 'Show is successfully updated');
}

So now, you can edit and update all the data into the database successfully.

Step 9. D – create delete row functionality

Write following code inside ShowController destroy function to to remove show row :

// ShowController.php
public function destroy($id)
{
        $show = Show::findOrFail($id);
        $show->delete();

        return redirect('/shows')->with('success', 'Show is successfully deleted');
}

We have completed a Laravel 6 CRUD operations tutorial with the example from scratch.

If you are interested in FrontEnd framework like Vue.js with Laravel or Angular with Laravel (Code is on Github as for this tutorial) :

  1. Vue Laravel CRUD example https://appdividend.com/2018/11/17/vue-laravel-crud-example-tutorial-from-scratch/
  2. Angular Laravel Tutorial Example https://appdividend.com/2017/09/22/laravel-5-5-angular-4-tutorial-example-scratch/

https://appdividend.com/2019/09/13/how-to-import-and-export-data-in-csv-excel-in-laravel-6/
https://appdividend.com/2019/09/13/laravel-6-generate-pdf-from-view-example-tutorial-from-scratch/
https://appdividend.com/2019/09/04/how-to-upgrade-laravel-valet-and-update-to-laravel-6/
https://appdividend.com/2019/04/08/laravel-collections-search-method-tutorial-with-example/
https://appdividend.com/2019/04/03/laravel-collections-filter-method-tutorial-with-example/
https://appdividend.com/2018/08/15/laravel-file-upload-example/
https://appdividend.com/2018/02/09/laravel-multiple-files-upload-tutorial-example/
https://appdividend.com/2018/02/08/laravel-ajax-validation-tutorial-scratch/
https://appdividend.com/2018/02/07/laravel-ajax-tutorial-example/


Laravel 6 continues the improvements made in Laravel 5.8 by introducing the following features.

  1. Semantic versioning – serverless deployment platform for Laravel, powered by AWS
  2. Compatibility with Laravel Vapor
  3. Improved authorization responses
  4. Job middleware
  5. Lazy collections
  6. Sub-query improvements
  7. The extraction of frontend scaffolding to the laravel/ui Composer package

https://appdividend.com/2018/10/31/how-to-use-php-in-visual-studio-code/ – For PHP Developers.

See https://github.com/slavkoss/fwphp/ (J:\awww\www\readme.md).

B12phpfw does not use jQuery and AJAX, see examples in https://github.com/slavkoss/fwphp/tree/master/fwphp/glomodul/z_examples/AJAX

11. PHP CMS – XAMP 64 bit on Windows 10, flat files CRud (u, d in Op.Sys – WYSIWYG SimleMDE or Summernote) or relational DB tblrows CRUD

Revised 2020.03.26 Code download : https://github.com/slavkoss/fwphp
I made B12phpfw ver. 6 code skeleton on which are modules Mnu, Blog (Msg), Mkd and many PHP learning examples.

Conclusion for this and my previous 10 posts

Posts are organized as PHP learning book, so I change previous posts periodically !

5W of every activity (highest ideas, categories, eg in journalism…)

who: Web site – menu & CRUD code skeleton applied to 3 modules (wrong to say applications) : “Mnu”, “Blog (Messages, Msg)”, “Mkd” in dirs :

  1. WEBSERVERDOCROOT\fwphp\www (fwphp is group of applications, www is menu appl consisting of one module)
  2. WEBSERVERDOCROOT\fwphp\glomodul\blog (glomodul is “application global modules” = group of global modules, )
  3. WEBSERVERDOCROOT\fwphp\glomodul\mkd

where(is code) : All Sites level Globals, Modules Globals, Menu code skeleton, Config classes, Crud classes.

when: Clear visible programming stepssignal flow, data flow & code flow

what: Basic Menu & CRUD code skeleton for (who)

how:

  1. FUNCTIONAL (DECLARATIVE) NAMING – descriptions of WHAT, NOT HOW STEPS -eg not programming steps M, V, C. Directory named invoice_fmb, means bussiness proces, not how steps (ee not 3 dirs M, V, C for all modules – fmb-s) !
  2. index.php is MAIN MODULE’S SINGLE ENTRY POINT ee all (submenus) calls go through this script. Here is configuration minimized, CONVENTIONS maximized. Same all other modules.
  3. simple OWN DEBUGGING and XDEBUG.
  4. CLASSES FOR: Config, (Controllers), Models (CRUD), not for Views but could be.
  5. namespaces & own autoloading class scripts. Composer’s PSR-4 is problem for not 3 dirs M, V, C for all modules but each module in own dir (huge difference) ?
  6. pagination in Blog pages
  7. beautiful urls without web server url rewritting (see QS=”?” constant.
  8. search/filtering/sort in Blog pages
  9. password_verify and password_hash functions explained (in z_examples)
  10. RTE (Rich Text Edit) markdown (SimpleMDE & Parsedown MD2HTML) or HTML (Summernote)

why: Not found hows above in learning sources : Simplest possible code skeleton, newest PHP coding style, good code explanations – code help.

Main (Root) module contains main index.php

www subdir in fwphp dir contains root module, site’s index.php. Has links on many test-learn examples.

Mkd module is Dreamweaver replacement

Can WYSIWYG edit:

  1. markdown using SimpleMDE or other
  2. or html using Summernote or other.

No relational database CRUD (so code is simpler) but similar, based on same B12phpfw fw (program skeleton) as Msg realational DB tables rows PDO CRUD module, so Mkd is good for learning MVC framework skeleton coding. I think B12phpfw is best-simplest DB PDO CRUD framework (for framework haters which also am I partially: it is not framework, it is standardized basic code skeleton) . Why version 6 ? B12phpfw is good example how small but important changes in fw code cause:

  1. lot of work
  2. and when done much simpler use of basic code skeleton.

 

PREREQUISITES FOR PHP WEB DEVELOPMENT

1. XAMPP 64 bit, php 7.4.2 https://www.apachefriends.org/download.html (I do not use WAMP SERVER anymore)

If no XAMPP (more work) : PHP (for Windows thread safe) : php 7.4.x needs VC15 or VS16 (Visual Studio 2017 or 2019 compiler respectively) Apache : https://www.apachelounge.com/download/

2. CONFIG SCRIPTS see 00info_php2.php – all config scripts are here

J:\xampp\apache\conf\httpd.conf J:\xampp\apache\conf\extra\httpd-vhosts.conf C:\Windows\System32\drivers\etc\hosts J:\xampp\php\php.ini

3. CONNECT PHP 7.2.4 TO OracleXE 11.2

ORACLE 11g PDO & OCI8 EXTENSION – OPTIONAL

php_pdo_oci.dll comes with XAMPP.

In php.ini extension=pdo_oci and extension=php_oci8_11g.dll (.dll is optional, not required)

oci8.default_prefetch = 100

https://pecl.php.net/package/oci8 (for XAMPP on Windows thread safe) ver. 2.2.0

2018-12-10 copy 1_php_oci8-2.2.0-7.4-ts-vc15-x64.zip to J:\xampp\php\ext and unzip php_oci8_11g.dll .

CLI PHP : J:\xampp\php\php.exe (before I used J:\wamp64\bin\php\php7.2.9\php.exe)

ORACLE 11g OCI8 EXTENSION ON NETWORK : OR for PC on on network ? : Feb 6 2018 Christopher Jones : ORACLE CLIENT LIBRARIES of same 32-bit or 64-bit architecture as PHP and are first in PATH. If you use Instant Client you need to have the correct VS Redistributable, see

  1. 64 bit http://www.oracle.com/technetwork/topics/winx64soft-089540.html or
  2. 32 bit http://www.oracle.com/technetwork/topics/winsoft-085727.html

4. COMPOSER DEPENDENCY MANAGER FOR PHP (CODE DOWNLOADER)

For XAMPP on WINDOWS just install https://getcomposer.org/Composer-Setup.exe from page https://getcomposer.org/download/ .

WAMP does not like php in PATH variable. So composer update does not work. [*master] J:\awww\w\fwphp> J:\wamp64\bin\php\php7.2.9\php.exe C:\composer\composer.phar update (1) or better C:\composer\composer7.bat : Save the file along with the originally installed composer.bat @echo OFF :: in case DelayedExpansion is on and a path contains ! setlocal DISABLEDELAYEDEXPANSION J:\wamp64\bin\php\php7.2.9\php.exe “%~dp0composer.phar” %* Now call php7 composer with the new command: [*master] J:\awww\w\fwphp> composer7 selfupdate (1.7.2, Use composer self-update –rollback to return to version 1.7.1) composer7 update (2) is same as (1)

5. GIT MULTIUSER SCRIPTS SYNCHRONIZER see Git book

see https://github.com/slavkoss/fwphp#swfw

 

WAMP 64 bit 2018-05-25 on Windows 10 64 bit – I do not use WAMP or ZWAMP anymore

Seems simpler than ZWAMP – no entries in PATH variable. Composer works after reinstal (asks php.exe dir) – see below.

Composer manual Command-line installation – I do not use this

For XAMPP on WINDOWS just install https://getcomposer.org/Composer-Setup.exe from page https://getcomposer.org/download/ .

To automate the installation on Linux only, use the guide on installing Composer programmatically.

  1. Deinstall Composer if installed
  2. cd J:\wamp64\www\fwphp J:\wamp64\bin\php\php5.6.35\php.exe -v PHP 5.6.35 (cli) (built: Mar 29 2018 14:27:15) Copyright (c) 1997-2016 The PHP Group Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
  3. J:\wamp64\bin\php\php5.6.35\php.exe -r “copy(‘https://getcomposer.org/installer‘, ‘composer-setup.php’);”J:\wamp64\bin\php\php5.6.35\php.exe -r “if (hash_file(‘SHA384’, ‘composer-setup.php’) === ‘544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061’) { echo ‘Installer verified’; } else { echo ‘Installer corrupt’; unlink(‘composer-setup.php’); } echo PHP_EOL;” outputs : Installer verifiedJ:\wamp64\bin\php\php5.6.35\php.exe composer-setup.phpoutputs : Composer (version 1.6.5) successfully installed to: J:\wamp64\www\fwphp\composer.phar Use it: php composer.pharJ:\wamp64\bin\php\php5.6.35\php.exe -r “unlink(‘composer-setup.php’);”The 4 lines above will, in order:
    1. Download the installer to the current directory
    2. Verify the installer SHA-384 which you can also cross-check here https://composer.github.io/pubkeys.html
    3. Run the installer – will check some php.ini settings, warn you if they are set incorrectly, and then download the latest composer.phar in the current directory
    4. Remove the installer
  4. Create a new composer.bat file alongside composer.phar: J:\wamp64\www\fwphp>echo @J:\wamp64\bin\php\php5.6.35\php.exe “%~dp0composer.phar” %*>composer.bat
  5. Add directory J:\wamp64\www\fwphp to your PATH environment variable if it isn’t already. For information on changing your PATH variable, please see this article https://www.computerhope.com/issues/ch000549.htm and/or use Google.
  6. Close your current terminal. Test usage with a new terminal: C:\Windows\System32>composer -V Composer version 1.6.5 2018-05-04 11:44:59

9. Main development, test and production menu (& 3 sites) – PHP 7 RC5, Oracle 11g on Windows 10 all 64 bit

HOME – Download Win10 64 bit AMP config and three sites php scripts.

14.8.2016 I changed a lot, see my article 10. This article 9 can be used only for explanations but everything is in code in 1_3sites_mnu_crud_ver1.rar.

22.11.2015 code refactored – i uploaded sites code version 3, (SINGLETON UTILS-HELPERS CLASS, config_site.php…).

Scripts config_site.php, utls.php, utls_glbsetpg.php and lsweb.php explain most important changes. I hope this is final code skeleton, ver4 will be bug fixes and cosmetic updates. (In ver3 I tested only most important lsweb.php but testing others is good exercise – and it shows how difficult this job is).

Statements (functions) flow article (not yet uploaded) should link together all I wanted to say.

Every (vitual) host – I have them 3: dev, test, production – should have in its web site doc root script which tells web server where are resources which are outside doc tree (global fns, settings, css, imgs)

(Problem with resources outside web doc tree is that we need file_get_contents() fn which is disabled by some inet providers. But if you want own SOAP server eg for direct b2b copying einvoice xml – then every your user should have own web site (bad news for some not needed service brokers – posrednici).)

Most important are:
1. “path science” – unexplained enough in learning materials I met (for SPA script very different than for URL called script).
2. Statements (functions) flow (to understand SW & for debugging) – I shall soon write article 10 or 11 (?) about this (SOAP examples for copying xml across inet will also be soon).

I can not understand SPA & frameworks without above two explained. To me seems that framework authors intentionally do not explain important things about their scripts coding (there is to much commercial interests in free SW) – so we have 100 frameworks instead 5-6.

I am shure that Utils class should be, settings should be in global_config.php both outside web doc tree. Local settings in doc tree should owerwrite global.

Eg my : J:\awww\apl\dev1\config_site.php contais:

 < ?php
 // development site (virtual host on home PC) :
 // J:\awww\apl\dev1\config_site.php
//$_SERVER['DOCUMENT_ROOT'] = J:\awww\apl\dev1\
 // yii2 advanced site (virtual host on home PC) :
 // J:\awww\apl\dev1\zfw\yii205\frontend\web\config_site.php
 // J:\awww\apl\dev1\zfw\yii205\aplmy\backend\web\config_site.php
 // realpath
 use utlmoj\utlmoj as utl;
 $ds = DIRECTORY_SEPARATOR;
 /**
 * CONVENTION: sitedocroot/../zinc = eg J:/awww/apl/zinc
 * site does not know where (outside site doc tree) are global resources
 * (util scripts, css, img for all sites), so we must assign
 * 1. GLOBAL RESOURCES (INCLUDES) FOLDER :
 */
 $gloresdir = realpath($_SERVER['DOCUMENT_ROOT'].'/../zinc'); // 1.
 require_once($gloresdir.'/utls.php'); // 2. util (helper) scripts
 $utl=utl::uget(); // 3. get or create helper fns object (singleton)
 require_once($gloresdir.'/utls_glbsetpg.php'); // 4. global page properties
 /**
 * IN APPL (IN SPA) IF IT NEEDS C R U D :
 * 2. g l o b a l C R U D :
 * $dbi = 'sqlite'; $dsn = 'cars_makes_names_savings.sqlite';
 * require_once($gloresdir.$ds.'db_conn.php');
 * db_conn.php does:
 * 1. require_once($gloresdir.'/klase/dbi.php');
 * 2. require_once($gloresdir.'/tbl/zodiac_mdl.php);
 * CONVENTION for M D L of concrete tbl :
 * require_once($gloresdir.'/tbl/'
 * .str_replace('.php','_mdl.php', basename($curpgpath)));
 * 3. template crud script :
 * require_once($gloresdir.$ds.'crud.php');
 */
 // ******************************************
 //exit();
 ?>

I am not shure if Utils class should have static or non static or both methods & properties (because you need many years PHP programming experience to be shure). Properties of this two working ways are not clear to me and unexplained enough in my learning sources.

Pitty that somebody – PHP expert – which I am not – does not explain this somewhere.

2.Sept.2015 – site_ver2.rar – improved code for all scripts, eg for lsweb.php and added some dir icons and better presented/explained site dir structure (see awww_DIR_NOT_VISIBLE_TO_ME.txt).

This article is enough for (advanced) beginning PHP programming Oracle and SQLite CRUD. 
Articles 1 to 8 are supplementary info.

This article unites my posts 3. Zwamp menu and 5. CRUD simple table (example 1) with refactored code for 5. CRUD and my (I hope) final site directories structure.

Most important examples in this article (others are in site_verx.rar):

Example Šifrarnik – is not finished, but shows much. Model is table (id, few_columns)

Example web server directories listing – dir items listing can be extended with row filters, sorts, downloads… but so as it is is very useful for web development.
Model (input data) is DirectoryIterator().
I find lsweb.php very useful for web development:
J:\awww\apl\dev1\zinc\utl\ls.php          http://dev1:8083/zinc/utl/ls.php  (or with ?dir=J:\awww\apl\dev1)
J:\awww\apl\dev1\zinc\utl\lsweb.php

Code for article 3. Zwamp menu is also contained in  site_verx.rar – it is to complicated for real life sites (except if you like something like)  but is excellent for learning PHP.

 

Oracle example 1

Model (input data) is simple table (šifrarnik) (id, few_columns), but more than 50% programming techniques can be learned on this and next example.


J:\awww\apl\dev1\zinstalac\ddl\DDL_selfjoin.sql:
-- winkey+X -> Comm.prompt admin
C:
cd C:\oraclexe\app\oracle\product\11.2.0\server\bin
sqlplus hr/hr
sho user
CREATE TABLE ZODIAC (
  ID          NUMBER(10) NOT NULL,
  SIGN        VARCHAR2(11),
  SYMBOL      VARCHAR2(13),
  PLANET      VARCHAR2(7),
  ELEMENT     VARCHAR2(5),
  START_MONTH INTEGER,
  START_DAY   INTEGER,
  END_MONTH   INTEGER,
  END_DAY     INTEGER,
  PRIMARY KEY(ID)
);

CREATE SEQUENCE ZODIAC_SEQ;
CREATE or replace TRIGGER ZODIAC_PREINS_TRIG 
BEFORE INSERT ON ZODIAC 
FOR EACH ROW
BEGIN
  -- PRIOR TO 11G :
  SELECT ZODIAC_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
  -- 11G :
  --:NEW.MSG_ID := ZODIAC_SEQ.NEXTVAL;
END;
/
sho err

DML :
INSERT INTO zodiac VALUES (1,'Aries','Ram','Mars','fire',3,21,4,19);
INSERT INTO zodiac VALUES (2,'Taurus','Bull','Venus','earth',4,20,5,20);
INSERT INTO zodiac VALUES (3,'Gemini','Twins','Mercury','air',5,21,6,21);
INSERT INTO zodiac VALUES (4,'Cancer','Crab','Moon','water',6,22,7,22);
INSERT INTO zodiac VALUES (5,'Leo','Lion','Sun','fire',7,23,8,22);
INSERT INTO zodiac VALUES (6,'Virgo','Virgin','Mercury','earth',8,23,9,22);
INSERT INTO zodiac VALUES (7,'Libra','Scales','Venus','air',9,23,10,23);
INSERT INTO zodiac VALUES (8,'Scorpio','Scorpion','Mars','water',10,24,11,21);
INSERT INTO zodiac VALUES (9,'Sagittarius','Archer','Jupiter','fire',11,22,12,21);
INSERT INTO zodiac VALUES (10,'Capricorn','Goat','Saturn','earth',12,22,1,19);
INSERT INTO zodiac VALUES (11,'Aquarius','Water Carrier','Uranus','air',1,20,2,18);
INSERT INTO zodiac VALUES (12,'Pisces','Fishes','Neptune','water',2,19,3,20);

Scripts directory structure (SPA, MVC domain style)

SPA means scripts are included, only exceptionally URL called. So scripts see all $ variables as own.

In SPA is not posible using relative page adresses because path relative to included script is not relative to includer (SPA) script  – adresses syntax explained here must be used !! To learn dirs science is one of most difficult PHP beginning parts, and allmost NOT EVEN MENTIONED in PHP learning materials.

MVC domain style means Scripts directory structure is “one form (application) one dir (& its subdeirs if needed)”. MVC is basically old structured programming:

  1. initialize (bootstrap, config),
  2. manage (ctr),
  3. input (model),
  4. output (view).

It is interesting that no one MVC promotor mentions this simple truth. Names are most important, but working means not (only) inventing new names but understand+explain.

DDLs are in J:\awww\apl\dev1\zinstalac\ddl\,  eg above  DDL_selfjoin.sql contain also selfjoin DDL & for SQLite.

Global config scripts (.php, .css, .js…most important of all types !) are in J:\awww\apl\dev1\zinc\,  eg  utls.php.

Below zinc are dirs: utl (helpers), slike (img), js…

Three sites (Apache virtual hosts on home PC):

Development URL is http://dev1:8083/ is Windows dir J:\awww\apl\dev1.

Production URL is http://pro1:8083/  is Windows dir J:\awww\apl\pro1.

Simmilar are both test site adresses.

 

After huderts Oracle Forms 6i created from scratch (from existing form ctrl+c,v) in more then 15 years it seems to me, whatever they say :), for PHP & Oracle should be :

CONVENTIONS FOR BETTER SCRIPTS VISIBILITY

  1. No camelcase becouse name higher_lower is (to me) better visible then camelcase higherLower
  2. Scripts sufixes :
    1. controller scripts have no sufix
    2. other scripts :
      1. model scripts: _mdl, _val (validation scripts)
      2. view scripts: _frm, _tbl, _rep
  3. ctr / bootstrap scripts are NOT named index.php, but are named simmilar to DB table name which they (CRUD) manage.Beside script visibility, this enables us to have more/all small tables crud (forms) scripts in one dir.To many dirs is not practical and old principle “one form (application) one dir (& its subdeirs if needed)” is newest fashion (2015 year).
  4. GLOBAL configuration scripts are in $CNFGD=J:\awww\apl\dev1\zinc, eg $CNFGD.$DS.utls.phputls.php (with help of config not static class & namespace) defines PHP $  (adress) variables for all included scripts (SPA !!) (no constants except pi and simmilar). Conf. vars must be defined as $ vars in utls.php and not as concatenation of dirs in all index.php scripts, becouse :
    IF DIR TREE CHANGES -> WE CHANGE ONLY ONE PLACE: utls.php
  5. Some strange names are better for search or for name conflicts (eg zinc instead of includes, chcons instead configclass, this example zodiac…)

 

Example 2: Web server directories listing programs

Model (input data) is DirectoryIterator() dir items listing.

I find them very useful for web development:
J:\awww\apl\dev1\zinc\utl\ls.php          http://dev1:8083/zinc/utl/ls.php  (or with ?dir=J:\awww\apl\dev1)
J:\awww\apl\dev1\zinc\utl\lsweb.php

 Conclusion

I did not see advantages in my testings compared with programming techniques I explained in this article (and in other before):

  1. AngularJS 1.4.3 CRUD with Oracle 11g
  2. Yii 2.0.6 with PHP 7 beta 3
  3. FatFree PHP fw

But frameworks above:

  1. no Oracle DBI example for normal people given
  2. It seems to me they are unfinished – always in development (uncompatible new versions), always new fws appear.
  3. slower ( min ~ 150 kB code with uncertain future included),
  4. more complicated – another (more) programming languages
  5. They do not even mention reporting (php reports from Eustáquio Rangel or similar) or tab key -> enter key which I made with few lines Javascript code (see site_ver1.rar J:\awww\apl\dev1\zinc\key_pressed.js).
  6. I doubt if they are more productive – learn time for programming techniques I explained in this article is ~ as for them  (lot of time 🙂 )
  7. to many incompatibilities uncertain future (yii2, ng 2),

Until authors of fw sw convince us on CRUD examples I give in this article + master-detail example I can not believe their to simple / not clear CRUD examples.


~~~utls.php $test=1 ~~~end script J:\awww\apl\dev1\index.php   source   phpinfo~~~