Saturday, June 8, 2024

Specify types in API functions

Recently, I encountered a bug in my PHP code while I was making use of iyzico's payment API. The error message was  Fatal error: Uncaught TypeError: Iyzipay\RequestStringBuilder::appendArray(): Argument #2 ($array) must be of type ?array, Iyzipay\Model\BasketItem given. The root cause was a couple of calls away from appendArray which threw the error: I was passing an object of type BasketItem as input to the CreateCheckoutFormInitializeRequest.setBasketItems($basketItems) function. Since this function did not specify the type of $basketItems, it accepted any input without warnings from the IDE. As PHP is an interpreted language, you need to execute all code paths to ensure there are no bugs. Your best option is to let the IDE help you as much as possible, and one of the ways is to specify types, especially in API functions.

If the API had required an array type for the setBasketItems method, as in setBasketItems(array $basketItems), my IDE would have alerted me, saving me several hours. 

Given that PHP has supported type declarations for function parameters, including classes and arrays, since PHP 5.0 (2004, 20 years ago!), iyzico's API could have been better designed, avoiding unnecessary developer time wastage.


Thursday, June 6, 2024

PHP double quotes vs single quotes

Use double quotes (") when you want PHP to interpret special characters like \n as newlines. Use single quotes (') when you want the string to be taken literally without any special character interpretation.
// Using double quotes>
echo "This is a line\nAnd this is another line";
// Using single quotes
echo 'This is a line\nAnd this is another line';
Output:
This is a line
And this is another line
This is a line\nAnd this is another line

Sunday, June 2, 2024

The confusing 508 status code

Recently, UptimeRobot notified me that our site is down with HTTP status code 508 - Loop detected. The site recovered on its own after five minutes. On another occasion, a user reported seeing the message Resource Limit Is Reached when attempting to access our web app via a browser.

The standard definition of 508 says that it may be given in the context of the Web Distributed Authoring and Versioning (WebDAV) protocol and that it indicates that the server terminated an operation because it encountered an infinite loop. This was initially confusing, as I was not using any WebDAV and  the ini_set('max_execution_time', 300) in my PHP code would end hanging processes, which is consistent with the site recovering after 5 minutes.

Further research revealed that the 508 code could also signify that a Resource Limit Is Reached, a usage specific to CloudLinux environments, which deviates from the standard interpretation. In this case, Uptime Robot was applying the standard definition, whereas our hosting environment attributed a different meaning to the same code.

Ultimately, the issue was traced back to exceeding the maximum number of processes (NPROC) allocated to our web app. I am continuing to investigate the root cause.

Saturday, May 4, 2024

Web app connection troubleshooting checklist

Basic:
  1. Does your DNS A record point to the correct IP address?
  2. Does DNS checker show mostly green marks for your domain and does it show the expected IP address?
  3. Does ping <server IP address> get a response?
  4. Has at least 4 hours passed since you updated the A record?
  5. Does ping <domain name> show the expected IP address and get a response?
  6. Is your web server running?
  7. Is the web app called by your web server running?
Extra:
  1. Check if the correct ports are open and listening.
  2. Ensure no firewall rules are blocking access to the web server or specific ports.
  3. Review web server logs (e.g., Apache, Nginx) for any unusual entries.
  4. Verify that SSL certificates are valid and have not expired.

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