Tuesday, April 2, 2024

How I use chatGPT in my programming

Here are some examples of my programming prompts for chatGPT:
  1. Explain a concept that I am not familiar with: "What is .htaccess"
  2. Find the location of specific functionality in existing code: "Show file name and code snippet in bitcoin code for halving"
  3. Improve existing code: "Improve the following SQL query...", "Make the following code shorter/simpler..."
  4. Write code: "Display the Turkish Lira amount idiomatically in PHP 7.3"
  5. Translate concepts I know from Java/C++: "PHP 7.3 add an element to an array"
  6. Suggest unit tests for full coverage of a method/class.
Knowing algorithms and data structures and paying attention to performance has become much more important than memorizing implementation details because tools like chatGPT make it trivially easy to translate any algorithm to any programming language. Times have become harder for code monkeys and much better for software engineers.

Saturday, March 30, 2024

PHP 7.3 vs 7.4

In PHP 7.3, you can use type declarations in functions:

abstract class Controller {
    protected $registry;
    protected $customer,
    public function __construct(Registry $registry) {
        $this->registry = $registry;
    }
    public function getCustomer(): Customer {
        return $customer;
    }

But type declaration for the properties will cause errors like "Parse error: syntax error, unexpected 'Registry' (T_STRING), expecting function (T_FUNCTION) or const (T_CONST)":

    protected Registry $registry;
    protected Customer $customer;

Typed properties was introduced in PHP 7.4.

Tuesday, March 12, 2024

PHP: Checking if an image is WebP

Let's say you have a WebP image:

$this->image = imagecreatefromwebp('path/to/your/image.webp');

If you want to check if an image is a resource, In PHP 7.3 the following returns true:

is_resource($this->image)

In PHP 8.0, the behavior changes because the GD library's image resources are replaced with GdImage objects. This change means that image resources created with GD functions, like imagecreatefromwebp(), no longer return a resource type. Instead, they return an instance of the GdImage class. In other words, for a WebP image, is_resource($this->image) returns false and for PHP 8, you should update your code as follows:

is_resource($this->image) || $this->image instanceof GdImage

Tuesday, March 5, 2024

Adding WebP preview to dropify.js

My web app uses dropify.js for image uploads. Dropify was last updated 7 years ago on March 19, 2017. I recently updated images from PNG/JPEG to WebP for smaller files size. Although the WebP image format was officially announced by Google on September 30, 2010, I could not preview them with dropify:

To solve this problem, I wrote dropifyPreviewFix.js.

If you want to batch convert your PNG/JPEG files to WebP, you can use convertToWebP.php.

Monday, March 4, 2024

Optimizing website speed and memory usage

The web app for the online marketplace I've been maintaining experienced significant slowdowns as the number of products on the site increased. Page load times reached 20 seconds, making the site unusable. Over the past three days, I have used the Chrome browser's built-in Lighthouse tool to analyze the issue and have implemented several optimizations.

I initially aimed to reduce image sizes. On average, WebP format consumes 4x less memory than JPEG for product photos. For PNG images, I've observed file size reductions of up to 100x. In total, converting images to WebP decreased server disk and memory footprint by 7x. This also has a positive effect on client LCP.

I implemented lazy loading to load only the image data visible on the screen, rather than loading all images at once. Additionally, by using infinite scrolling to load only the HTML text of the visible portion, the initial memory usage for the client-side webpage source text was reduced from 1,386,494 bytes to 57,977 bytes, achieving a 24x reduction. These size optimizations decreased load times from 20 to 13 seconds. Almost all of the remaining 13 seconds was initial server response time.

The most significant improvement in page load speed was achieved by eliminating N+1 query issues (using a loop instead of a single query) in the database queries. In my case, the inefficiency was fetching photos for each product in separate queries within a loop instead of fetching all the necessary photos in one query and then map them to their respective products. This enhancement reduced the initial server response time from 13 seconds to 2 seconds and the site became usable again.

I still have a lot of work to do to apply these techniques to other portions of the code, but at least now I know where to focus.

Music: Beck the Monster-Денис Пакрушов

Sunday, February 11, 2024

PHP array_merge

The array_merge function in PHP combines the elements of one or more arrays together so that the values of one are appended to the end of the previous one. If an array key exists in both arrays, the value from the second array will overwrite the value from the first array. Example:
$data['product']['desc']['url'] = 'xyz'
$post['desc'] exists, but $post['desc']['url'] does not exist.
$productEdited = array_merge($data['product'], $post)

Since $post['desc'] exists, it will overwrite $data['product']['desc'] in the resulting array. Because $post['desc'] does not have a 'url' key, after the merge, the 'url' key will not exist in the merged array's ['desc'] sub-array because the whole ['desc'] array from $post replaces the ['desc'] array from $data['product'].

To preserve the 'url' key while still merging the rest, you have to:
// Merge top-level arrays
$productEdited = array_merge($data['product'], $post);
// Manually merge 'desc' sub-array, ensuring 'url' is preserved:
$productEdited['desc'] = array_merge($data['product']['desc'], $post['desc']);

Saturday, January 27, 2024

Real time chat

In a web application, real time chat, i.e. sending/receiving messages without database polling and refreshing the page, can be implemented with socket.io as follows:
Note that besides a web server, you also need a chat server that coordinates messages and sends requests to web server to save chat messages to database.