Jump to content

Strider64

Members
  • Posts

    470
  • Joined

  • Last visited

  • Days Won

    12

Posts posted by Strider64

  1. I really don't understand what your asking? Pulling data from a database and styling the HTML with CSS are totally different from each other. Take my website - https://phototechguru.com/ for example the Home Page and the Gallery Page uses the same data (they don't have to) and are obviously different in appearance. Those two links look the same to me? I don't see why you could not use the same template? You might have to make a few minor tweaks, but I don't think it would be anything drastic?

     

    Here's the PHP for the gallery page:

            <?php
            $count = 0;
            foreach ($cms as $record) {
                echo '<div class="' . $displayFormat[$count] . '">';
                echo '<div class="gallery-item">';
                echo '<div class="images"><img src="' . $record['image_path'] . '" alt="Photo1" data-exif="' . $record['Model'] . ' ' . $record['ExposureTime'] . ' ' . $record['Aperture'] . ' ' . $record['ISO'] . ' ' . $record['FocalLength'] . '" width="800" height="534">';
                echo '</div>';
                $count++;
                echo '<div class="title">' . '<h1 class="pictureHeading">' . $record['heading'] . '</h1>' . '<span class="exifInfo">' . $record['Model'] . '</span>' . '</div>';
                echo '</div>';
                echo '</div>';
    
            }
            ?>

    here's the PHP for the index page:

            <?php foreach ($cms as $record) { ?>
                <article class="cms">
                    <img class="article_image"
                         src="<?= htmlspecialchars($record['image_path']) ?>" <?= getimagesize($record['image_path'])[3] ?>
                         alt="article image">
                    <h2><?= $record['heading'] ?></h2>
                    <span class="author_style">Created by <?= $record['author'] ?> on
                        <time datetime="<?= htmlspecialchars(CMS::styleTime($record['date_added'])) ?>"><?= htmlspecialchars(CMS::styleDate($record['date_added'])) ?></time>
                    </span>
                    <p><?= $record['content'] ?></p>
                </article>
            <?php } ?>

    Pretty darn similar in my opinion and they are totally different looking pages.

  2. 9 minutes ago, PeterBubresko said:

    First i get a good advice that was working. Then i get another advice because the first one wasn't good enough. I am just trying to learn something new here. The first og them works pefectly the way i want it to be. So why confuse me me with one more? Any way, i got to ask. What is the right way, and what is the best way? As long they are working and do theire job for me i dont realy see the problem or care. I just wanted the first words of a line to be bold.

    Gismola: Thank you so much for the link. I was looking at it, and that is just what i need. On the page you sent me to i found so much  more. I need more of those kind of sites, please? Thank you.

    There is really no 100 percent correct way of coding or in this case HTML/CSS, but most web designer/developers try to follow standard coding practices. If you want to decipher all the confusion then just go to https://validator.w3.org/ yourself. In my opinion HTML/CSS can pretty forgiving which can be a good or a bad thing.

  3. I been programming since the early 1980s, but I really didn't get started with website design and development until 2009 or 2010.  Like you, I was let go from a job were I spent almost 20 years working in the automotive paint business. Decided to change field and went back to college as I was collecting severance that helped. I earned a degree in Computer Graphics when I learned design first (HTML/CSS) and then started back end development PHP by teaching myself. I agree with Barand learn HTML/CSS and maybe a little JavaScript (Vanilla...no libraries like jQuery at least at first). It shouldn't take too long to learn HTML/CSS and I would advice staying away from Bootstrap until you get a firm grasp of HTML/CSS as in my opinion knowing CSS good leads to less headaches later on. Once you get a firm grasp of HTML/CSS then start tackling PHP. I recommend pure PHP and no Frameworks at first as that is just leads to taking shortcuts then when you run into a problem you might never really understanding the solution. One thing I learn the hard way is never try to write your own security code in PHP just use PHP's builtin security functions and/or use a trusted third party's application (PHPMailer or Swiftmailer comes to mind). Be very careful of tutorials on the internet and even the good ones are outdated somewhat as the programming world changes fast. That's where these types of forums come in handy. One thing over the years that I have learn first hand is designers and developers have big egos that can lead to some healthy "heated" debates. 😂 After awhile every programmer gets his or her own coding style and there's nothing wrong in that as long as it isn't fundamentally wrong.  

  4. I have done comment sections in the past in PHP and what I found useful is have two database tables. One for the main reply (thread) and the other for the replies that way if the thread should be deleted or messed up somehow (though I never had that happened) then simply delete the main thread id to the replies.

  5. Here's my PDO connection class that have used over the years. Maybe this will help?

    use mysql_xdevapi\Exception;
    use PDO;
    use PDOException;
    
    class Database {
    
        private PDO $_connection;
        // Store the single instance.
        private static ?Database $_instance = null; // Don't initialize before it is called:
    
        // Get an instance of the Database.
        // @return Database:
        protected static function getInstance(): Database
        {
            if (!self::$_instance) {
                self::$_instance = new self();
            }
            return self::$_instance;
        }
    
        public static function pdo(): PDO
        {
            $db = static::getInstance();
            return $db->getConnection();
        }
    
        // Constructor - Build the PDO Connection:
        public function __construct() {
            try {
            $db_options = [
                /* important! use actual prepared statements (default: emulate prepared statements) */
                PDO::ATTR_EMULATE_PREPARES => false
                /* throw exceptions on errors (default: stay silent) */
            , PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
                /* fetch associative arrays (default: mixed arrays)    */
            , PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
            ];
            $this->_connection = new PDO('mysql:host=' . DATABASE_HOST . ';dbname=' . DATABASE_NAME . ';charset=utf8', DATABASE_USERNAME, DATABASE_PASSWORD, $db_options);
            } catch (PDOException $e) {
                //echo $e;
                //echo "<pre>" . print_r($e->errorInfo, 1) . "</pre>";
                if ($e->errorInfo[1] === 1045) {
                    echo "User has the wrong credentials " . $e->errorInfo[1] . "<br>";
                    return false;
                }
    
                throw $e; // If PDO Exception error can't handle it throw it to Exception:
    
            } catch (Exception $e) {
                echo 'Caught exception: ', $e->getMessage(), "\n"; // Not for a production server:
            }
            return true;
        }
    
        // Empty clone magic method to prevent duplication:
        private function __clone() {
    
        }
    
        // Get the PDO connection:
        protected function getConnection(): PDO
        {
            return $this->_connection;
        }
    
    }

     

    to use simply do

    $stmt = Database::pdo()->prepare($sql);

     

    I just want to add this is just to add a PDO connection string to connect the Database Table, I would never send that error message on a production server.

  6. I personally don't use bootstrap, but I'm assuming it has grids? Anyways, I use grids and HTML for a two column format. A third column would be easy as well using CSS grids.

     

    Here's the two column form using grids:

    <main  class="content">
        <div class="container">
            <?php foreach ($cms as $record) { ?>
                <article class="cms">
                    <img class="article_image"
                         src="<?= htmlspecialchars($record['image_path']) ?>" <?= getimagesize($record['image_path'])[3] ?>
                         alt="article image">
                    <h2><?= $record['heading'] ?></h2>
                    <span class="author_style">Created by <?= $record['author'] ?> on
                        <time datetime="<?= htmlspecialchars(CMS::styleTime($record['date_added'])) ?>"><?= htmlspecialchars(CMS::styleDate($record['date_added'])) ?></time>
                    </span>
                    <p><?= nl2br($record['content']) ?></p>
                </article>
            <?php } ?>
        </div>
    </main>

    Here's a small section of the CSS:

    /* Approximately the size of a 1248px large display monitor */
    @supports (grid-area: auto) {
    
      @media screen and (min-width: 78em) {
        .site {
          display: grid;
          grid-template-columns: 1fr minmax(23.4em, 54.6em);
          grid-template-areas:
    				"header header"
    				"nav nav"
    				"main main"
                    "sidebar sidebar"
                    "footer footer";
          justify-content: center;
          width: 75em;
          margin: 0 auto;
        }
        .masthead {
          grid-area: header;
          background-image: url(../images/img-header-001pg.jpg);
          background-repeat: no-repeat;
        }
        .checkStyle {
          grid-area: main;
          font-size: 1.2em;
        }
    
        .sidebar {
          grid-area: sidebar;
          justify-content: center;
        }
    
    
      } // End of Screen Size
    } // End of Last Grid Area

    Using grids cuts down on the CSS as well as the HTML, plus CSS really should be in a separate file and not inline. I'm assuming it's your CSS, but I'm sure you can have CSS from bootstrap that is an external fire as well that you can change?

    • Thanks 1
  7. I was bored today and decided to take a break from my own develop, so I decided to fool around with this and see if I could help.

    I don't know exactly what you are doing and I only used one database table to do this.

    However, I think what you are after can easily be modified? If not that's OK as I said I was bored. 😂

    I don't know why you don't use MySQL to pull in the range values of the prices?

    I created a mythical Bicycle Shop called Rocket Bicycles :

        <table id="products">
            <tr>
                <th colspan="4">The Rocket Bicycles Inventory</th>
            </tr>
            <tr>
                <th>Record</th>
                <th>Product</th>
                <th>Price ($)</th>
                <th>Quantity</th>
            </tr>
    
        </table>

    and I used Vanilla JavaScript (I find that is just as easy and is easily transferable)

    'use strict';
    (function () {
        let data = {};
        /* The Following can easily be put into HTML via js */
        data.min = 0;
        data.max = 2000.00;
    
        /* Handle General Errors in Fetch */
        const handleErrors = function (response) {
            if (!response.ok) {
                throw (response.status + ' : ' + response.statusText);
            }
            return response.json();
        };
    
        const productCard = function (record){
            /* Get the Table Id */
            const table = document.getElementById('products');
            /* Create the Table Row element */
            const tr = document.createElement('tr');
    
            /* Create the necessary Elements for the column data */
            const id = document.createElement('td');
            const product = document.createElement('td');
            const price = document.createElement('td');
            const quantity = document.createElement('td');
    
            /* Append the Table Row element to the Table */
            table.append(tr);
    
            /* Append the Column Row data to the Table Rows */
            tr.append(id);
            tr.append(product);
            tr.append(price);
            tr.append(quantity);
    
            /* Assign the appropiate class to the table data row */
            /* Give the appropiate table data the corresponding data */
            id.classList.add('normal_format');
            id.textContent = record.id;
    
            product.classList.add('product_format');
            product.textContent = record.product;
    
            price.classList.add('money_format');
            price.textContent = "$" + record.price.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');
    
            quantity.classList.add('normal_format');
            quantity.textContent = record.quantity;
        };
    
        /* Success function utilizing FETCH */
        const inventoryUISuccess = function (records) {
    
            /* Grabing the record data from the Database Table
             * and assigning the value of the objects to the
             * HTML table using a forEach statement in
             * Vanilla JavaScript.
             */
            records.forEach(record => productCard(record));
        };
    
        /* If Database Table fails to load then hard code the correct answers */
        const inventoryUIError = function (error) {
            console.log("The Darn Database Table did not load", error);
        };
    
        /* create FETCH request for check answers */
        const price_range = function (url, succeed, fail) {
            fetch(url, {
                method: 'POST', // or 'PUT'
                body: JSON.stringify(data)
    
            })
                .then((response) => handleErrors(response))
                .then((data) => succeed(data))
                .catch((error) => fail(error));
        };
    
        price_range('rockets_inventory.php', inventoryUISuccess, inventoryUIError);
    
    })();

    the PHP for the "Fetching of the Data":

    <?php
    
    require_once 'assets/config/config.php';
    
    /* Makes it, so we don't have to decode the json coming from javascript */
    header('Content-type: application/json');
    
    /*
     * The below must be used in order for the json to be decoded properly.
     */
    try {
        $data = json_decode(file_get_contents('php://input'), true, 512, JSON_THROW_ON_ERROR);
    } catch (JsonException $e) {
    }
    
    /*
     * Grab the database table data that meets the price requirements
     */
    $sql = 'SELECT id, product, price, quantity FROM rocket_bicycles WHERE price >= :min AND price <= :max ORDER BY price ';
    $stmt = $pdo->prepare($sql); // Prepare the query:
    $stmt->execute(['min' => (float)$data['min'], 'max' => (float)$data['max']]); // Execute the query with the supplied data:
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    /*
     * If everything validates OK then send success message to Ajax / JavaScript
     */
        if (isset($result)) {
            output($result);
        } else {
            errorOutput('There is a darn problem!');
        }
    
    /*
     * Throw error if something is wrong
     */
    
    function errorOutput($output, $code = 500) {
        http_response_code($code);
        try {
            echo json_encode($output, JSON_THROW_ON_ERROR);
        } catch (JsonException) {
        }
    }
    
    /*
     * After converting data array to JSON send back to javascript using
     * this function.
     */
    function output($output) {
        http_response_code(200);
        try {
            echo json_encode($output, JSON_THROW_ON_ERROR);
        } catch (JsonException) {
        }
    }

    and here's the SQL for the database table

    -- phpMyAdmin SQL Dump
    -- version 5.1.1
    -- https://www.phpmyadmin.net/
    --
    -- Host: localhost:8889
    -- Generation Time: Oct 08, 2021 at 11:24 PM
    -- Server version: 5.7.34
    -- PHP Version: 8.0.8
    
    SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
    START TRANSACTION;
    SET time_zone = "+00:00";
    
    --
    -- Database: `php_sandbox`
    --
    
    -- --------------------------------------------------------
    
    --
    -- Table structure for table `rocket_bicycles`
    --
    
    CREATE TABLE `rocket_bicycles` (
      `id` int(11) NOT NULL,
      `product` varchar(60) DEFAULT NULL,
      `price` float(6,2) NOT NULL,
      `quantity` int(6) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    --
    -- Dumping data for table `rocket_bicycles`
    --
    
    INSERT INTO `rocket_bicycles` (`id`, `product`, `price`, `quantity`) VALUES
    (1, 'Banana Rocket', 499.99, 5),
    (2, 'Pink Lady ', 499.99, 8),
    (3, 'Speed Demon', 999.98, 2),
    (4, 'Quick Silver', 1500.00, 1),
    (5, 'Lucky Lady', 300.00, 7);
    
    --
    -- Indexes for dumped tables
    --
    
    --
    -- Indexes for table `rocket_bicycles`
    --
    ALTER TABLE `rocket_bicycles`
      ADD PRIMARY KEY (`id`);
    
    --
    -- AUTO_INCREMENT for dumped tables
    --
    
    --
    -- AUTO_INCREMENT for table `rocket_bicycles`
    --
    ALTER TABLE `rocket_bicycles`
      MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;
    COMMIT;

    and a little bit of css:

    #products {
      font-family: Arial, Helvetica, sans-serif;
      border-collapse: collapse;
      width: 90%;
      margin: 0 auto; }
    
    #products td, #products th {
      border: 1px solid #ddd;
      padding: 8px; }
    
    #products tr:nth-child(even) {
      background-color: #f2f2f2; }
    
    #products tr:hover {
      background-color: #ddd; }
    
    #products th {
      padding-top: 12px;
      padding-bottom: 12px;
      text-align: center;
      background-color: #04AA6D;
      color: white; }
    
    .normal_format {
      text-align: center;
      width: 6.250em; }
    
    .product_format {
      text-align: left;
      width: 6.250em; }
    
    .money_format {
      width: 3.125em;
      text-align: right; }

    Sorry for the long post, but I hope it helps:

    • Like 1
  8. On 10/1/2021 at 8:21 AM, SLSCoder said:

    The correct answer to this question is that it cannot be done.
    That is, there is no way using PDO or mysqli prepared statements to create stored procedures from client form inputs as parameters and therefore no way to prevent sql injection.

    The reason is that prepared statement parameters (PDO or mysqli) cannot be saved as part of a query. The parameters the database, not as part of the sql.

    The PHP code to create the prepared statement and if not still cached the MySql work to optimize the prepared statement must be executed every time the prepared statement is used.
    If the prepared statement is to be run repeatedly the parameters must be stored initially and then retrieved every time the prepared statement is called.

    I think it would be worthwhile to find better ways than prepared statements to prevent sql injection.

    When I first started coding in PHP there was a person on here (I can't remember his name) that helped me out a lot. I was hung up on securing my code and spent all night writing a script that I thought was "secure" then the next day I posted it here. He replied back to me and the first thing he wrote was to throw that script in the trash. He went on to say people who write security code work in teams and test them out before they are introduced to the wild (internet). There is nothing wrong with prepared statement and unless you are a large corporation the speed of prepared statements is fast enough. Prepared statements are as secure as they possibly can be and nothing is 100 percent secure. So I totally disagree on the use of prepared statement.

    • Like 1
  9. Remember, people are not there to see what is actually happening or what you are doing. The solution that you get that works might be something that you don't understand, but a person who helped you who put his or her time in should at least be thanked. At least you acknowledge and thanked that in the last post that you made. I once had someone help me with a PHP script that I didn't understand and even to this day still don't after deciphering it, but it worked and there wasn't another solution out there. So I used it anyways as I spent too much time on the particular part of the script. There are a lot of times I don't understand what something does, but only to have a light-bulb go on in my head months or even years later. Object-oriented programming is something that I could do, but really never understood the meat & potatoes of it until now. It's starting to make a lot of sense now and to me that is what is fun with it comes to coding. 

    • Great Answer 1
  10. Pagination is simple to do, but you need to actually want to learn it.

     

    Here's what I call a mini tutorial on how to do it though it uses PDO instead of mysqli, but the principle is the same.

     

    Here's a function that I wrote:

    /*
     * Pagination Format
     * Read all the data from the database table in an array format
     */
    function readData($pdo, $table, $page, $perPage, $offset) {
        $sql = 'SELECT * FROM ' . $table . ' WHERE page=:page ORDER BY date_added DESC LIMIT :perPage OFFSET :blogOffset';
        $stmt = $pdo->prepare($sql); // Prepare the query:
        $stmt->execute(['perPage' => $perPage, 'blogOffset' => $offset, 'page' => $page]); // Execute the query with the supplied data:
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    Here's how to implement it:

    /*
     * Using pagination in order to have a nice looking
     * website page.
     */
    
    if (isset($_GET['page']) && !empty($_GET['page'])) {
        $current_page = urldecode($_GET['page']);
    } else {
        $current_page = 1;
    }
    
    $per_page = 1; // Total number of records to be displayed:
    
    /*
     * Grab total records (rows) in a database table
     */
    function totalRecords($pdo, $table, $page = 'blog') {
        $sql = "SELECT count(id) FROM " . $table . " WHERE page=:page";
        $stmt = $pdo->prepare($sql);
    
        $stmt->execute([ 'page' => $page ]);
        return $stmt->fetchColumn();
    
    }
    
    /* Total number of records that NEEDS to be displayed */
    $total_count = totalRecords($pdo, 'cms');
    
    
    /* calculate the offset */
    $offset = $per_page * ($current_page - 1);
    
    /* calculate total pages to be displayed */
    $total_pages = ceil($total_count / $per_page);
    
    /* Figure out the Pagination Links */
    $links = links_function('index.php', $current_page, $total_pages);
    
    /* Finally, call for the data from the database table to display */
    $cms = readData($pdo, 'cms', 'blog', $per_page, $offset);

    I don't know if it will help the OP any, but it should help others as well. 😉 I just want to add figuring out the Links isn't that hard to figure out and it shouldn't affect the pagination part, but it's pretty useless without it. I figure I can't do everything. 😉😃

  11. 9 hours ago, Moorcam said:

    Is it worth the price though? What does it offer that say, Sublime Text or Visual Studio Code doesn't? Asking for a friend :D

    I used Notepad++ for years and recently started to use Sublime Text.

    While PHPStorm is subscription based, it's pretty good in my opinion and for an IDE it has helped my PHP skills a lot. It makes suggestions on how to write the code in a better way that I would never have thought of and makes syntax errors easy to resolve. I am not affiliated with JetBrains as I just like using their developer tools as it simplifies my coding a lot. 

    • Like 1
    • Great Answer 1
  12. 27 minutes ago, TechnoDiver said:

    Yea, that becomes more clear the more experience I get. I've already made a separate HTML class, I'll work on repositioning the logic. I'm catching what you're throwing out there now. Thanks

    I personally like leaving the HTML on the page itself as I like doing HTML/CSS mock-ups then just adding to the PHP to the HTML.

    For example -

    <main>
        <?php foreach ($cms as $record) { ?>
        <article class="cms">
            <img class="article_image"
                 src="<?php echo htmlspecialchars($record['image_path']); ?>" <?= getimagesize($record['image_path'])[3] ?>
                 alt="article image">
            <h2><?= $record['heading'] ?></h2>
            <span class="author_style">Created by <?= $record['author'] ?> on
                        <time datetime="<?= htmlspecialchars(CMS::styleTime($record['date_added'])) ?>"><?= htmlspecialchars(CMS::styleDate($record['date_added'])) ?></time></span>
            <p><?= nl2br($record['content']) ?></p>
            <?php echo (isset($_SESSION['id'])) ? '<a class="editButton" href="edit.php?id= ' . urldecode($record['id']) . '">Record ' . urldecode($record['id']) . '</a>' : null; ?>
        </article>
        <?php }
        $url = 'index.php';
        echo $pagination->new_page_links($url);
        ?>
    </main>

    I have a Database Object class

    An example (not the whole code) -

    namespace Techshangri;
    
    use mysql_xdevapi\Exception;
    use PDO;
    use PDOException;
    
    class DatabaseObject // The Parent Class:
    {
        static protected string $table = ""; // Overridden by the calling class:
        static protected array $db_columns = []; // Overridden by the calling class:
        static protected array $objects = [];
        static protected array $params = [];
        static protected $searchItem;
        static protected $searchValue;
    
        /*
         * Pagination static function/method to limit
         * the number of records per page. This is
         * useful for tables that contain a lot of
         * records (data).
        */
        public static function page($perPage, $offset, $loc = 'index'): array
        {
            $sql = 'SELECT * FROM ' . static::$table . ' WHERE page=:page ORDER BY date_added DESC LIMIT :perPage OFFSET :blogOffset';
            $stmt = Database::pdo()->prepare($sql); // Prepare the query:
            $stmt->execute(['perPage' => $perPage, 'blogOffset' => $offset, 'page' => $loc]); // Execute the query with the supplied data:
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        }
    
        // more code...

    and I have a Children's class that is more specific:

    Children's Class (CMS.php) - Example -

    class CMS extends DatabaseObject
    {
        protected static string $table = "cms"; // Table Name:
        static protected array $db_columns = ['id', 'user_id', 'thumb_path', 'image_path', 'Model', 'ExposureTime', 'Aperture', 'ISO', 'FocalLength', 'author', 'heading', 'content', 'data_updated', 'date_added'];
        public $id;
        public $user_id;
        public $page;
        public $thumb_path;
        public $image_path;
        public $Model;
        public $ExposureTime;
        public $Aperture;
        public $ISO;
        public $FocalLength;
        public $author;
        public $heading;
        public $content;
        public $date_updated;
        public $date_added;
    
        /*
         * Construct the data for the CMS
         */
        public function __construct($args = [])
        {
            //        $this->user_id = $args['user_id'] ?? null;
            //        $this->author = $args['author'] ?? null;
            //        $this->heading = $args['heading'] ?? null;
            //        $this->content = $args['content'] ?? null;
            //        $this->date_updated = $args['date_updated'] ?? null;
            //        $this->date_added = $args['date_added'] ?? null;
    
    
            // Caution: allows private/protected properties to be set
            foreach ($args as $k => $v) {
                if (property_exists($this, $k)) {
                    $v = static::filterwords($v);
                    $this->$k = $v;
                    static::$params[$k] = $v;
                    static::$objects[] = $v;
                }
            }
        } // End of construct method:
    
        public static function styleTime($prettyDate): string
        {
            try {
                $dateStylized = new DateTime($prettyDate, new DateTimeZone("America/Detroit"));
            } catch (Exception $e) {
            }
    
            return $dateStylized->format("Y-m-d H:i:s");
        }
        
        // more code...

    I use Active Record Design Pattern as for what I do doesn't get too complex and besides I'm starting to like this pattern. However, if I was doing a really large website I would go more the route of Model-View-Controller pattern. Well, at least I think I would? Anyways, I getting off topic and my point is that after struggling with OOP for awhile, I found out by doing tutorials and looking at examples is to keep your methods and even you classes as short as possible, plus try to have meaning to them that is helpful to you as the coder. The real benefit now is that I can transfer these classes over to other projects (websites) with no problem and that is when I find out if I have written a class that could had been written better.  As I sometimes find myself getting a little carried away with a class or putting a method (or even the variables) in the wrong class. I always shoot myself when I do that when come to that realization. 🤣 Everyone codes differently, but that is my logic.

    • Like 1
  13. 2 hours ago, ChenXiu said:

    p.s. in my real scripts, I have:
    $result = $db->query($query);
    while ($row = $result->fetch_assoc()) { ... }

    (otherwise none of my mySQL queries would work)
    But when I type my question here, I goofed it up.
    I'm noticing the following:
    I have at least 20 new coding ideas every single day. Whenever I try them out, they  *always* generate some sort of an error.
    ... and then I have to go fix the error.
    Each time.
    Looking back this entire year, I think every single block of code I've written has generated some sort of an error which I have to go fix.

    ... hopefully this gets better 😃

    I feel like a first grader in english class....
    "The dog jumped over the fense."
    - oops.... "fence"
    "The three bares liked porridge"
    - oops... "bears"
    while($row = $result = fetch_assoc()....
     

    A good thing to have is a good IDE that will point out the common syntax errors and find good resources/tutorials online to help with the logic flow. As for Database Tables I like using PDO and I still go to the following online resource when I get stump or have a brain fart. https://phpdelusions.net/pdo 🤣

    I go here and other forums to see if someone before me has had the same problem and if not I will attempt to ask a question while showing my work. I learn over the years not to show too little or way too much code. I find commenting code help not only me but the people helping me trying to solve my problem(s).

    • Like 1
  14. From what I am see is that you are doing too much inside methods and even the classes. Keep methods simple as possible such as the following example:

        public static function page($perPage, $offset, $loc = 'index'): array
        {
            $sql = 'SELECT * FROM ' . static::$table . ' WHERE page=:page ORDER BY date_updated DESC LIMIT :perPage OFFSET :blogOffset';
            $stmt = Database::pdo()->prepare($sql); // Prepare the query:
            $stmt->execute(['perPage' => $perPage, 'blogOffset' => $offset, 'page' => $loc]); // Execute the query with the supplied data:
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        }

    Classes can be inherited from a parent class or even another child class (However, I wouldn't go too deep) There are other ways of doing inheritance as well and some people frown on doing the way I do, but from what I do is small compared to larger development places.

    class CMS extends DatabaseObject
    {
        protected static string $table = "cms"; // Table Name:
        static protected array $db_columns = ['id', 'user_id', 'thumb_path', 'image_path', 'Model', 'ExposureTime', 'Aperture', 'ISO', 'FocalLength', 'author', 'heading', 'content', 'data_updated', 'date_added'];
        public $id;
        public $user_id;
        public $page;
        public $thumb_path;
        public $image_path;
        public $Model;
        public $ExposureTime;
        public $Aperture;
        public $ISO;
        public $FocalLength;
        public $author;
        public $heading;
        public $content;
        public $date_updated;
        public $date_added;
    
        /*
         * Create a short description of content and place a link button that I call 'more' at the end of the
         * shorten content.
         */
        #[Pure] public static function intro($content = "", $count = 100): string
        {
            return substr($content, 0, $count) . "...";
        }

    I do that with my PDO Database Connection that I call the Grandparent (called Database and I utilize it by doing Database::pdo() ).  I go by the the K.I.S.S. (Keep It Simple Stupid) model as I find out that I write less code and can be used over and over again. I find myself (as I sure others do to) when I try to get fancy and write a bunch of code it leads to write more code with the class end up being longer than they should. Granted having a long class is sometimes unavoidable, but even them after you gain more knowledge of PHP can be streamline. I learn something new everyday in PHP coding (and other languages) and sometimes I slap myself why didn't I think of that. 🤣

  15. Actually using Fetch in Vanilla JavaScript is pretty easy to do: (Here's an example)

        /* Success function utilizing FETCH */
        const sendUISuccess = function (result) {
            //console.log('Result', result);
            if (result) {
                d.querySelector('#recaptcha').style.display = "none";
                submit.style.display = "none";
                notice.style.display = "grid";
    
                notice.textContent = "Email Successfully Sent!";
                notice.style.color = "green";
                message.style.display = "grid";
                //messageSuccess.style.display = "block";
                d.querySelectorAll('form > *').forEach(function (a) {
                    a.disabled = true;
                });
            }
        };
    
        /* If Database Table fails to update data in mysql table */
        const sendUIError = function (error) {
            console.log("Database Table did not load", error);
        };
    
        const handleSaveErrors = function (response) {
            if (!response.ok) {
                throw (response.status + ' : ' + response.statusText);
            }
            return response.json();
        };
    
        const saveRequest = (sendUrl, succeed, fail) => {
    
            fetch(sendUrl, {
                method: 'POST', // or 'PUT'
                body: JSON.stringify(sendEmail)
    
            })
                .then((response) => handleSaveErrors(response))
                .then((data) => succeed(data))
                .catch((error) => fail(error));
        };

    though jQuery has jQuery.get() I believe which is the same thing as Fetch in Vanilla JavasScript which might be worth looking into? In my opinion it easier and coding is more logical.   I like that you don't have to worry about parsing the data and handling errors is easy to do. In your case you could make a fallback option or tell the other player that the other person is no longer online.

  16. Why don't you just extend the child class?

     

    Does it work in the parent class? If it doesn't then there is something wrong with self::$conn

     

    You might be initializing the database connection before it is called?

  17. I would suggest using namespaces and an autoloader using composer. A good link in my opinion is this one - https://phpenthusiast.com/blog/how-to-autoload-with-composer and it really help me understand on how to do it.

     

    Then you simply can do this :

    <?php
    require_once 'assets/config/config.php'; // You still need your trusty configuration file
    require_once "vendor/autoload.php"; // Autoloader using composer
    
    use PhotoTech\CMS;
    use PhotoTech\Pagination;

    Here's my Database Class:

    <?php
    
    
    namespace PhotoTech;
    
    use PDO;
    class Database {
    
        private PDO $_connection;
        // Store the single instance.
        private static ?Database $_instance = null; // Don't initialize before it is called:
    
        // Get an instance of the Database.
        // @return Database:
        protected static function getInstance(): Database
        {
            if (!self::$_instance) {
                self::$_instance = new self();
            }
            return self::$_instance;
        }
    
        public static function pdo(): PDO
        {
            $db = static::getInstance();
            return $db->getConnection();
        }
    
        // Constructor - Build the PDO Connection:
        public function __construct() {
            $db_options = array(
                /* important! use actual prepared statements (default: emulate prepared statements) */
                PDO::ATTR_EMULATE_PREPARES => false
                /* throw exceptions on errors (default: stay silent) */
            , PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
                /* fetch associative arrays (default: mixed arrays)    */
            , PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
            );
            $this->_connection = new PDO('mysql:host=' . DATABASE_HOST . ';dbname=' . DATABASE_NAME . ';charset=utf8', DATABASE_USERNAME, DATABASE_PASSWORD, $db_options);
        }
    
        // Empty clone magic method to prevent duplication:
        private function __clone() {
    
        }
    
        // Get the PDO connection:
        protected function getConnection(): PDO
        {
            return $this->_connection;
        }
    
    }

    I have been using it for sometime without any problems

    and to use it I simply do the following

     

    class DatabaseObject // Extended by the children class:
    {
        static protected string $table = ""; // Overridden by the calling class:
        static protected array $db_columns = []; // Overridden by the calling class:
        static protected array $objects = [];
        static protected array $params = [];
        static protected $searchItem;
        static protected $searchValue;
    
        /*
         * There is NO read() method this fetch_all method
         *  basically does the same thing. The query ($sql)
         *  is done in the class the calls this method.
         */
        public static function fetch_by_column_name($sql)
        {
            $stmt = Database::pdo()->prepare($sql); // Database::pdo() is the PDO Connection 
    
            $stmt->execute([ static::$searchItem => static::$searchValue ]);
            return $stmt->fetch(PDO::FETCH_ASSOC);
        }
    
        // More coding...

    I should mention I am using PHP 8, so there might be some adjustment that might be needed?  I also make comments that are sometime mental notes to me in order to know what I was doing. 😉

  18. Where static really shines is when you using an Active Record Design Pattern (I would assume other patterns are the same way, but this is the only pattern that I have used so far), for example:

    The Data Object Class

    class DatabaseObject // Extended by the children class:
    {
        static protected string $table = ""; // Overridden by the calling class:
        static protected array $db_columns = []; // Overridden by the calling class:
        static protected array $objects = [];
        static protected array $params = [];
        static protected $searchItem;
        static protected $searchValue;
    
    // More code....

    A Children Class example

    class CMS extends DatabaseObject
    {
        protected static string $table = "cms"; // Table Name:
        static protected array $db_columns = ['id', 'user_id', 'thumb_path', 'image_path', 'Model', 'ExposureTime', 'Aperture', 'ISO', 'FocalLength', 'author', 'heading', 'content', 'data_updated', 'date_added'];
    
    // More Code....

     

  19. /* if(isset($_GET['page'])) {
      $page = $_GET['page'];
    } else {
      $page = 1;
    } */
    
    if ( isset($_GET['page']) ) {
      $current_page = $_GET['page'];
    } else {
      $current_page = 1;
    }
    
    $per_page = 20; // $num_per_page = 20;
    
    
    $offset = $per_page * ($current_page - 1)
    
    //$sql 	= "SELECT * FROM people ORDER BY id ASC LIMIT $start_from, $num_per_page";
    $sql = 'SELECT * FROM people ORDER BY id ASC LIMIT ' . $per_page . ' OFFSET ' . $offset . ';

    I think this will work, but I'm just taking an educated guess. You are going to need know the total number of records, so that you don't go pass the total records in your database table using your previous and next links.

    HTH Helps?

     

    Though I do have pagination working on my own website - https://www.phototechguru.com/

    • Like 1
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.