Dev Log - dev - 2024-01-26 02:47:30

Sun Jan 7 23:26:58 UTC 2024

Installation of components (on openbsd)

$ pkg_add vim php mariadb-server php-mysqli php-zip
$ cd /etc
$ cp examples/httpd.conf ./
$ vim httpd.conf 
$ vim php-fpm.conf
$ rcctl enable php-fpm
$ rcctl ls all | grep php
$ rcctl enable php82_fpm
$ rcctl start php82_fpm
$ rcctl enable httpd
$ rcctl start httpd
$ cd /var/www/htdocs/
$ vim index.php
$ mysql_install_db 
$ rcctl enable mysqld
$ rcctl start mysqld
$ mysql_secure_installation 
$ install -d -m -o _mysql -g _mysql /var/www/var/run/mysql
$ vim /etc/my.cnf
$ rcctl restart mysqld

/etc/httpd.conf (no ssl yet):

# $OpenBSD: httpd.conf,v 1.22 2020/11/04 10:34:18 denis Exp $
server "default" {
    listen on * port 80
    directory index index.php
    location "*.php" {
    fastcgi socket "/run/php-fpm.sock"

The import line in /etc/my.conf :

socket = /var/www/var/run/mysql/mysql.sock

The important line in /etc/php-fpm.conf (this was the default at the time of installation (OpenBSD 7.3));

listen = /var/www/run/php-fpm.sock

Enable mysqli and zip in /etc/php-8.2.ini :


loading/unloading the database


$ mysql -u root < dbinit.sql


$ mysqldump -u root -p www > dbdump.sql


$ echo "drop database www" | myqsl

project organization

everything is thrown into /lib and /assets . Eventually I will sort /lib into /bin (for the do\ script) and into /includes for the templating components.

page template engine

header file with 3 functions, htmlheader($title) , htmlbody($content) , htmlfooter($js) . The assembly of a document is as simple as building the title, content, and adding whatever js the page requires then executing these scripts in order.

Currently, the login page does not support the htmlbody() function and instead outputs directly to the page. the doregister.php file cannot use the htmlbody() function because I want the script to stop execution as soon as possible in the event of an error.

session configuration

values that need to be checked and set in /etc/php82.ini :

session.save_handler = files
session.use_strict_mode = 1
session.use_cookies = 1

; breaks everything without ssl
;session.cookie_secure = on 

session.use_only_cookies = 1 = PHPSESSID
session.auto_start = 1

; 0 destorys the on browser exit, 86400 expires the session after a day
session.cookie_lifetime = 86400

session.cookie_path = /
session.cookie_domain = localhost
session.cookie_httponly = true
session.cookie_samesite = "Strict"
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.sid_length = 26
session.trans_sid_tags = "a=href,area=href,frame=src,form="
session.sid_bits_per_character = 5

Mon Jan 8 16:59:21 UTC 2024

Session debugging.

php locks the session file when sessionstart() is called. This file will not unlock until sessionwriteclose() is called. No multithreading. Additionally, the value of $SERVER['SERVERNAME'] must match the name of the vhost in your httpd configuration file. Additionally, the session.cookiedomain variable in the php.ini must match the name. On the test server it is wise to set these all to the same ip address, in production all of these should be set to a FQDN.

mysql debugging

  • it's probably a syntax error
  • it might be a database error
  • it was a syntax error

Tue Jan 9 20:41:00 UTC 2024

SQL joins

  • inner join: returns records that have matching values in both tables
  • left outer join: returns all records from the left table and the matched records from the right table
  • right outer join: returns all records from the right table and the matched records from the left table
  • full outer join: returns all records when thereis a match in either left or right table

SQL unions

  • no


Does not support:

  • nested lists
  • tabs in pre blocks (it assumes you want to start another pre)
  • syntax highlighting
  • nested block quotes

Thu Jan 11 15:51:09 UTC 2024


  • sha256 hashes of every post are saved into a table
  • when creating a new post or editing an existing post, the shasum is checked to assure every post is original
  • same system is appplied to comments but it uses a different hash

Voting system

  • users can submit a grade from 0 to 100 once
  • average is taken from all votes and a grade letter is assigned

Fri Jan 12 22:01:25 UTC 2024

parametrizing everything

Every sql query that that does not take user input has been left as an unprepared query (for marginal performance gains). Every sql query that takes user input as an argument (even from the database itself) has been parameterized.

In other words

query with no arguments -> query();

query with an argument from the user or database -> prepare(); bindparam(); execute();

fix css

on user creation, default css colors are added to the database

fix page layout

moved half the nav to the bottom page so it won't overflow on mobile

securing the server

move database.sql file and server configuration outside of the document root.

$ mv lib/serverconf.php ../../ 
$ mv dbinit.sql ../../

Sat Jan 13 23:04:25 UTC 2024

Bug fixes

Browsers do not cache the content of html forms so there was an issue with inserting content. If the post/comment did not satisfy the constraints it would be lost to time. Possible ways around this was JS or AJAX (JS) but I do not like this solution. Instead, my solution is to display a form with the user's input on the submission page if there is some error with the content.

Mon Jan 15 21:04:47 UTC 2024

exporting data

I added two ways to export data: as a .csv and as a .zip. I also added the ability to delete posts

RSS the planet

Added per user rss feeds and sitewide rss feed.

Fri Jan 26 01:41:25 UTC 2024

Licensing system

I added a license chooser. In your mypage.php you can choose a default license that will automatically be applied to your pots. Absence of a license is also supported (although copyright is implicit). Currently, creative commons, public domain, copyleft, and copyright are supported.

account deletion

Account deletion involves some amount of spaghetti code but it mostly works (I think?).

The process is somewhat complicated because I am an SQLlet

  1. get all posts for the user
  2. get all comments for these posts
  3. delete comment hashes for the comments of the posts
  4. delete comments for the post
  5. delete post hashes for posts
  6. delete ratings for posts
  7. delete the post
  8. delete the user

there is probably an easier way but prepared statements work.

This post has no votes.