Jump to content

gizmola

Administrators
  • Posts

    6187
  • Joined

  • Last visited

  • Days Won

    167

Everything posted by gizmola

  1. This sounds like the use cases that people use CRM's for.
  2. Certainly an option, although I think the HTML 5 date input is far superior to that from a user experience standpoint. It also has a built in Calendar popup, and you can pass various attributes that conform the date range as needed. I have taken advantage of this quite a bit, as I have had a need to set minimum/maximum date ranges, and these are all supported by the html5 input type.
  3. Javascript runs on the client. So if this is really for some sort of auction site, you need to consider how the server figures into this, because client code and data can not be trusted. I don't know what these clocks indicate, or how the user will interact with them, but you need to understand that, even if your code starts a countdown, the expiration of that countdown is not reliable and can not be used, to allow/disallow a bid for example. Any auction timers must rely on the server for validation. Also I don't know where you got that code, but you should go back to the drawing board, even though mac_guyver did show you how you could make that work. The first sign that code is bad is the use of the var keyword, which means all your variables are global. ES6 was released in 2015, so the recommended use of things like block scoping of variables using const and local, as well as string templates, arrow functions, promises and destructuring are all features of modern javascript for over 11 years now. Another option that would make sense, would be the use of a Class. You likely would want the timers to utilize Promises, which is another feature that was introduced in ES6. Another technique that will often be applied to a problem like this is the use of an Immediately Invoked Function Expressions (IIFE). An IIFE is a popular javascript technique for data hiding/making internal data private.
  4. Yes, use the technique that @Barand demonstrated. What is missing, and very important is your html form, with the specific field you are using. With HTML5 you can for example utilize an input with type="date". I would recommend using that, as well as html5 in general for your html pages, which is the current standard. While you can never fully trust user input to be valid, at least with HTML5 you can program to the assumptiion that the format of the date string that PHP receives from the form will be in RFC 3339/ISO 8601 format, which is YYYY-MM-dd. The format the user sees in the form will match their localization settings. When I say that you can not trust it, I mean that there are tools that can be used to submit form data directly without going through the HTML page, and for this reason, you always need to do additional validation on the backend. So you might want to validate that the date that has been submitted is infact of the format of 9999-99-99, and not some other format that will probably not work correctly, like 12/01/2023 or any other "string". If the user submits the data using your form, it will be correct, and will also be a "real" date, thanks to the built in browser handling of the "date" input type. Knowing this, you can expect that the date strings will work as Barand demonstrated in his code snippet.
  5. Command line php has a linter (syntax checker) built into it. php -l /path/to/file.php Most PHP Integrated developer environments (IDE's) have a syntax checking built into it. The generally accepted best IDE for PHP is Jetbrains PHPStorm, but VSCode or Codium with the installation of https://intelephense.com/ plugin is a suitable free/low cost option. If you want to try it out, you should make sure to follow the installation instructions, which involves uninstaling a plugin that comes with vscode and will interfere with intelephense. These tools do numerous things to show you what syntax errors you have. Last but not least, there are numerous AI LLM's that you can point at the code and will diagnose problems.
  6. Sounds like a penny wise pound foolish exercise. Of course things will be slow if processes have to be started frequently. Of course there will be additional power usage. The question is: what is the expected average and peak usage? You state this is for a client. If the server PS is underpowered, then it's likely to fail. What will the cost be, when the server PS burns out, perhaps damaging the entire machine? Servers typically feature redundancy so that they don't die when a single component has a fault (ie. having multiple PS's, RAID controllers, RAID configuration and hot swappable drives.). Why would you use a box that isn't designed to be a server, as a server, and then attempt to micro optimize and skimp on the PS? If the usage of this environment is such that there is low to no usage during specific periods, then perhaps you can economize by configuring the box to sleep and wake on lan. You didn't provide any information on what services it will be providing. I don't have much else to offer other than that IIS is infamous for its instability, particular if you require additional IIS Modules. If you've gone through the exercise of trying to reduce overhead, and remove/turn off non essential services, then you've already optimized the server to reduce OS and cpu utilization, and if the box isn't doing anything then power consumption will already be low.
  7. This is some confusing code -- you are creating a pdf purely to then create an image out of it. Since you are throwing away the pdf, I have to think there's a more direct way to do this, either with imagemagick directly or using some existing library designed for making graphs and charts. With that said, if it works on one machine and not the other, and everything else is the same, then you have to consider the environment settings and what might be different (error levels, permissions, etc.). A few comments: It's best not to have a php close tag in your scripts. This and other recommended coding standards are documented here: https://www.php-fig.org/per/coding-style/ I bring this up because whenever you are returning output, a closing tag with whitespace following can lead to to some strange and confusing behavior, and has long been one of the reasons people encounter the "output already sent" message. There is also little to no reason to have code that is trying to clean up resources -- especially in a script like this, when php garbage collects everything when the script ends. Having a script that defines a class only to use it in the same script in which it was defined is an anti pattern, you should try and avoid. PHP also has namespaces, composer as both a dependency manager and autoload builder. You are using php 8.5, yet creating and writing code the way people did it 15 years ago.
  8. Welcome to the world of PHP development. It is unfortunately the case that for some reason, most people new to php development, particularly using Windows, still default to the installation of Xampp. My first comment is that Wamp/Mamp/xampp etc. are all projects that haven't been used by professional developers in a long time. This change in approach to local development was hastened by the commodity support of virtualization built into intel and amd cpu's. Every PC that is more powerful than a potato supports virtual environments. Developers first started developing with or within virtualized environments using software like Vmware workstation and Virtualbox in the mid to late 2000's. It's important to understand virtualization, and how it is the basis for cloud and vps servers. This was an evolution that began close to 20 years ago at this point. Many professional developers were developing PHP apps within virtualized linux systems back in 2007-2008. The orchestrator "Vagrant" was released in 2010 with a 1.0 version in 2012 and was for a time, the favored approach for many developers and development teams as a way to harness the virtualbox and VMware hypervisors to build simplify and orchestrate virtual linux based environments. I might add that Windows now includes it's own microsoft provided hypervisor - hyper-v, so the option to run fully virtualized servers within windows is still an option for development on a windows workstation. Xampp is an antiquated approach to php development with many drawbacks including: It's based on LAMP (Linux, Apache, MySQL, PHP) in a particular configuration that few websites use anymore for various reasons The once popular apache/mod_php integration has been superceded by the use of the php_fpm server component other http servers/proxies are often used, with nginx being a common choice. It's a wrapper for windows native ports of the components. PHP apps aren't deployed to windows servers -- they are deployed to Linux servers 99.9% of the time It makes no sense to develop your application in an environment you won't be deploying to, and there are also OS specific differences which means that some php code that works in a linux environment won't work under windows and vice-versa Developers are often unaware that they have installed local server components which are running (unless they proactively start/stop them) all the time. These projects (xampp, wampserver, easyphp, mamp..... and many others) have been dying off due to lack of interest, and have to be updated frequently, requiring re-installation. It's old, and ugly, and people have been coming up against problems with them for over a decade, or finding that their favorite environment package has fallen behind or been abandoned entirely. Windows based developers should prefer the use of windows application installation through package managers (Chocolatey, Scoop, Winget etc.) just as Mac users prefer homebrew, and linux users utilize distro specific package managers (apt, yum/dnf, flatpak, etc). Again these windows package tools utilize a cli environment, rather than the old "find a website, download a .exe setup, run it and hope this new program does what you need it to do." The setup of tools and disconnect in how apps can or should be deployed from development to product leads to confusion The configuration files that are used to configure apache and php is hidden from the user competent professional php development involves learning the basics of cli tools, use of git, and the composer cli tool. Xampp is intended to "simplify" by hiding the cli, and thus discourages and sends the message to a new developer that they don't need to use the cli, which is counterproductive Windows users have a variety of far better options with the main 2 being: use WSL to install a linux distro integration, and work within WSL fast, performant and makes the development experience closer to what osx and linux developers do use Docker based environments Provides the ultimate degree of project by project flexibility and can provide a local development environment that includes an orchestrated set of server components that would be extremely difficult to set up locally using any alternative approach. Easily switch between php versions/databases/http servers on a project by project basis Is supported by multiple projects that simplify the use of docker (DDEV, Lando, Docksal -- others) I advise most people to install DDEV now The only thing Xampp is going for windows based developers now, is teaching old mostly obsolete development. If a tutorial or article starts with the use of Xampp, it almost always provides bad advice and techniques and code samples that no experienced developer would use. There are numerous resources that can be used to study and learn modern PHP development, and anyone running windows can find numerous existing resources (tutorials, guides, articles, free and paid online courses) that will show you how to use wsl or docker/ddev. This will also lead you to understand and become proficient in the use of component libraries and frameworks. These things tend to come together once you start to understand the use and purpose of composer, which should be the first step (after making a project directory) you should be using (unless a tool like DDEV or the symfony cli tool has run done that setup for you).
  9. As I understand it, PHPRunner is a PHP Code generator. Most of the people who frequent this forum are or have been PHP Developers, and I doubt seriously that anyone has ever used PHPRunner. Just speaking generally, PHP Sessions are basically containers for a set of variables on a server that are associated with a user. Sessions are not a database. Technically, they are just PHP variables that PHP will "serialize" and "deserialize" for you. A running script can add, remove and change session variables, and PHP will load the contents of those variables each time the same user makes a new HTTP request, which the server does based on a cookie value. Usually for something like a member/user system, you would have a database table called user or member, that has the email field and a password field, and that table will also have a primary key, which is usually a sequentially assigned integer. The specifics of this depend on the database being used. It looks to me like PHPRunner can support a number of different databases. Typically, a new visitor to the site, with no existing session cookie will be assigned one, whether or not they have logged in. Once they do login successfully, many systems will read the email and user_id value from the database and set a session variable like $_SESSION['is_logged_in'] = true. The system can then use this as well as the user's unique id value, and can use this to "guard" any screen that requires login, including a form that allows the user to add or update data associated with them. That data will typically use the user's user_id to "relate" the user's data to their user table row. As this id number is kept on the server and never accepted as user input, there is no way for someone to change or add data that doesn't belong to them, unless you create code that is incompetent. The specifics of this have to do with relational database design which is a entire subject line of its own. Beyond this conceptual description, I can't really help you any further as I have no idea how PHPRunner creates code that supports these standard ideas, but I have to assume that it is designed to generate code that does once you understand it. My best advice to you is to seek support from the company that makes it, or try their forums. Best of luck!
  10. It would help if you stated what your problem is. It's not clear at all, exactly what issue you are having. In general setting the From address to be someone who filled out a form, is spoofing, and not the way to handle this. You can not send mail to yourself on behalf of another user, without that looking like you are spoofing. You also can't "open relay" mail on behalf of others, which is another common mis-configuration issue which will get you blacklisted, and in some cases dropped by your hosting company. In other words, when you send mail, if you want it to be delivered, you either have to work within what your hosting company allows (which will disallow both spoofing and open relaying) or you need to set up your mail sending so that it neither spoofs nor relays mail. Using SMTP (which exists for direct mail server to mail server transfer). The email you are attempting to drop off needs (and ultimately will) come from an email server that will accept it. The email should come from a fixed legitimate user authorized to send email from your server, and there are many ways for that to happen and potential complexities that are connected to the configuration of your server and hosting. Your code is attempting to use the SMTP protocol, but it can't send mail directly to another user without having support for all the things that email servers require (SPF, DKIM, DMARC, MX, Valid Reverse DNS entries) if you want to avoid blacklists/and spam or outright rejection of the email. Looking at what it appears you are trying to do, I would suggest that you modify things to that you utilize the configured MAIL_FROM_ADDRESS constant, and change the toAdmin method so that it sets the reply to as the user. You should stop spoofing the from address, for the reasons I already mentioned. Unfortunately the poorly written Mailhelper wrapper class is in the way of the PHPMailer class method you need to call which is: $mailhelperObj->addReplyTo($inputs['email', $inputs['name']); The way the MailHelper class is written you would need to alter public function handleMail(string $subject, string $body, string $to_address, string $to_name, string $from_address, string $from_name): PHPMailer And add a new parameter which would probably be "?string $reply_to" -- like so: public function handleMail(string $subject, string $body, string $to_address, string $to_name, string $from_address, string $from_name ?string $reply_to = null ): PHPMailer Inside the handleEmail method you would want to have something like this: if ($reply_to) { $this->mail->addReplyTo($reply_to, $from_name); $from_name = MAIL_FROM_NAME; } The reason I'd reset the $from_name here, rather than adding the user provided name, is that I think it's probably a bad idea with any mail client to have the same email address associated with a revolving door of different names, so once the reply to is set, I'd reset it so the actual mail sender did not include the <some name> label, which produces that disconnect. In other words you don't want an email from "[email protected] <some person>" and then the next time someone uses the contact form, having an email that is "[email protected] <different person>". When you reply to the person, your email client will use the reply to using their actual email address, which is the reason you were trying to spoof the from email in the first place. With these changes as a basis, changing the "toAdmin()" method should be fairly obvious, and I already did more refactoring for a question like this, than I like to do for questions from "non php developers" who just want someone to fix their code for them.
  11. Excellent questions, hopefully I'll clarify. These days, most projects have a "project" name. So I'm assuming you will follow that convention. It doesn't matter what it is, but as most people will use git and a git remote like github or bitbucket to push their code to, usually the name will be whatever the github repo name is. That is totally up to you, but for this example, I'm going to assume the name is "mailer_site". I tend to develop projects on my workstation within a "Projects" directory under my home user, and I will make a subdirectory under that for each project, although sometimes if I have groups of projects I'll use multiple nested folders. It really doesn't matter how or where you do this, although as a windows user I would advise that you avoid creating directory names with spaces in them, or using mixed case. If you want to have an space in the name, use an underscore as in my example. So your project directory path in these examples assume the local username is "gizmo" and so will be: # Path to projects C:\Users\gizmo\Projects # Path to new project C:\Users\gizmo\Projects\mailer_site In your terminal you want to CD into this directory to run your "composer init". Personally, I am a big fan of installer systems for most local installations. I use "brew" for the mac, and for windows "Chocolatey". I didn't mention this, but a great way to install composer is to enter an administrator terminal and run "choco install composer". If all goes as plan, you shut that terminal, open your user terminal and composer should be ready to use globally. If you haven't looked at it, check out Chocolatey. There are others like winget that serve a similar purpose. I install most if not all developer languages and tools, editors etc using the chocolatey cli, as it takes care of a many annoying details and makes upgrades or uninstalls easy. Commands like "pwd" are useful in the terminal to verify the path. Thus all the "meta files" will be in the root of this project directory. If you follow the steps I mentioned, in this directory you will have opened the terminal (non administrator terminal), and created the directory for your project, and used cd to enter it. Now run composer. One other detail I didn't mention, is that for "minimal stability" enter "stable". When complete you should see something like this Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 12/29/2025 7:06 PM src d----- 12/29/2025 7:07 PM vendor -a---- 12/29/2025 7:07 PM 374 composer.json -a---- 12/29/2025 7:07 PM 4274 composer.lock Notice that composer made the src and vendor directories. (If you look in vendor you'll see the phpmailer lib directory structure and the autoload.php file that composer generated, and you will want to require for "runable" scripts. The composer.json file should look something like this: { "name": "gizmo/mailer_site", "type": "project", "autoload": { "psr-4": { "Gizmo\\MailerSite\\": "src/" } }, "authors": [ { "name": "Gizmola", "email": "gizmola@...." } ], "minimum-stability": "stable", "require": { "phpmailer/phpmailer": "^7.0" } } At this point, you want to add additional directories. Most projects follow a skeleton the same or similar to the one Described here: https://github.com/php-pds/skeleton?tab=readme-ov-file That project readme has a nice table showing additional folders/directories you may or may not want to add. For example, people who create unit tests will use the /tests folder and create additional folders beneath it. Obviously that is way beyond the scope of your question. If this is intended to be a cli tool, you might want to have "bin" directory, and some projects might want to have a var directory which often will have subdirectories of log and or cache, for generated files (common to template libraries which compile templates to php scripts), and other things. The most important concept however, is that the webroot of the running webserver will be the {project}/public directory! A lot of people use docker these days and will often have additional files and directories off the project root, and meta files like a docker-compose.yml file. For git you will want a .gitignore, and many projects also will include .env files here (although you don't want to save those in your repository). At minimum, I would add these folders to the project: mkdir public mkdir config mkdir tests # Should see something like this if you DIR Directory: C:\Users\gizmo\Projects\mailer_site Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 12/29/2025 7:21 PM config d----- 12/29/2025 7:22 PM public d----- 12/29/2025 7:06 PM src d----- 12/29/2025 7:22 PM tests d----- 12/29/2025 7:07 PM vendor -a---- 12/29/2025 7:07 PM 374 composer.json -a---- 12/29/2025 7:07 PM 4274 composer.lock So your "webroot" will something like: C:\Users\you\Projects\mailer_site\public The web/document root for your webserver is the setting that needs to specify this directory. In the "public" folder, you should put other folders that need to be in webspace. Like any "html" project these are typically folders like: css, js, image etc. Inside this folder, as an example, you will start with an "index.php" file. What you will have is then some code like this: Notice all the things that are NOT beneath the webroot including: any of your meta/config files, configuration files like .ini or any other files that might have credentials or configuration info. Your application classes or function libraries (which should be inside the src directory). Nor will the libraries you've required (which are in the vendor directory). You can refer to any of these files as needed using require, although libraries and classes you create in the src directory will be automagically loaded as needed using proper php namespaces, but the autoloader will resolve for you. So here is a base index.php file to start you off: <?php // public/index.php use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\SMTP; use PHPMailer\PHPMailer\Exception; define('PROJECT_HOME', dirname(__DIR__)); require(PROJECT_HOME . '/vendor/autoload.php'); // Right out of the phpmailer docs $mail = new PHPMailer(true); //etc... You might notice the constant definition as that is a convenient way to generate relative paths. You can also refer to files in config this way using "require(PROJECT_HOME . '/config/settings.php'); or whatever else you might need to load or refer to on the filesystem. This way you don't hardcode paths to a specific installation. At this point there is not much more to it, again if you understand how PHP namespaces work. Just to demonstrate how you might add a class of your own, relative to the PSR-4 convention which has associated the namespace of "Gizmo\\MailerSite\\": "src/", any folder you create within the src directory will have the namespace of "Gizmo\Mailersite". If you create a subdirectory the namespace will then be extended using that name, however you can simply place a class file inside the directory. In this example, if you create a class in the src directory with the name "MyApp.php" with these contents: <?php namespace Gizmo\MailerSite; class MyApp { private string $name; public function __construct(string $name) { $this->name = $name; } public function getName() { return $this->name; } } You can then refer to this class using the namespace configured in the composer.json. <?php // public/index.php use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\SMTP; use PHPMailer\PHPMailer\Exception; use Gizmo\MailerSite\MyApp; define('PROJECT_HOME', dirname(__DIR__)); require(PROJECT_HOME . '/vendor/autoload.php'); $app = new MyApp('My Mailer App'); // Right out of the phpmailer docs $mail = new PHPMailer(true); echo $app->getName(); I should note that you do not have to go so far as to supply a full namespace, particularly if the application is going to be self contained. Many projects (and frameworks will use the convention of associating /src contents with the "App" namespace, as in: "autoload": { "psr-4": { "App\\": "src/" } }, So in that case, the same class would be referred to via the namespace of: use App/MyApp; Assuming you have a local cli php version installed with composer, you could run this as a simple test using php's built in webserver. You would cd into the public directory and start the development server: cd public php -S localhost:8000 Open localhost:8000 with your browser and the code provided should work with no errors and display "My Mailer App".
  12. As you noted, Composer is a dependency management tool. In that way it is not different from tools for other languages like npm for javascript. The best way to handle this is to install composer globally on your system. Composer has a windows installer here: https://getcomposer.org/Composer-Setup.exe Download and run it, and it should set up composer for global use on your system. After installation you should be able to run this from any directory. composer -V Once installed, open a terminal and change to the directory of your project. Ultimately, in order to understand modern PHP development you need to understand namespaces, and use them in your own code. You have a few options, but the best one is to run "composer init" in this directory and answer the questions it prompts you for. The first question will be a prompt for your "vendor"/"package". It's not important for your own project what you make these names, but you want to use some sort of name that identifies you. If you have a github account, your github name would be a good choice. This will be used along with the package name you provide as the namespace for any classes you create. You will place these inside the {project_dir}/src directory that will be created by composer. You do not need to add dependencies at this point, so just answer no to those questions. Once completed, it will have created a simple composer.json and composer.lock file, as well as the /src directory. At this point you are ready to add any libraries you want to use. You'll find similar instructions for most libraries, but to install phpmailer, again from the project directory root you will run: composer require phpmailer/phpmailer You should note that composer will create a vendor directory where all libraries (and any dependent libraries) are placed and referenced. You want to keep both the composer.json and the composer.lock files in your project source code, as you use these to replicate your project from development to production. Once you have things setup read the instruction for phpmailer in their github repo: https://github.com/PHPMailer/PHPMailer Notice that any of your scripts that actually are executed need to include the autoloader file generated, as illustrated in their documentation. Once piece of advice: have a subdirectory in your project where these "controller" scripts go. A controller script is any script that will be directly referenced from the webroot. This is far beyond a simple introduction to this, but most projects utilize a "front controller" (ie. index.php) through which all routing and control passes. All the well known MVC frameworks use this pattern to bootstrap apps, so that everything passes through this front controller script. If you manage something like that for your app you vastly improve security and make things simpler and easier to manage, and in particular only need the autoloader to be required in that one script, but again it just needs to be required in any script that is under the webroot. You do not want all your project files or the vendor directory or the src directory to be inside the webroot. So for this to work, you will also want to create a directory in your project directory, most commonly named "public". You then make {project_dir}/public your webroot for your development site and ultimately for your production version and put things that should be available from the webroot (including static files like css, js etc.) in subdirectories under public. While there is a lot more to this topic, hopefully you have enough now to get started.
  13. I don't do much with Wordpress other than to host some sites for friends, but looking at your code, there's certainly not enough information to do anything more than to hazard a guess here. Just looking at the docs for wp_enqueue_style, plugin styles are loaded before the main site css, so if your goal is to override some styles and you aren't seeing them, that could be because you need to to override this default ordering which you can do in the add_action function, by providing an addtional parameter to override the default ordering of 10. add_action( 'wp_enqueue_scripts', 'progeny_css', 50); Just from a debugging standpoint "'...but a couple of things I've tried aren't working. I've cleared my cache..." is not debugging information that is helpful. You have to be specific about what you expected and what you got in terms of the loaded css that's available in your browser development tools.
  14. So here's one of the options that's incredibly easy: use Symfony's HttpFoundation component, which across the PHP world is one of the most used Component libraries: See here for a partial list. It provides a formal OOP interface to HTTP Requests and Responses, Cookies, sessions and anything else that people get from the primary cgi-bin superglobals. This can add value to any php based web app, but at minimum you could use it to handle setting partitioned cookies. It's as easy as adding to your project using composer composer require symfony/http-foundation creating your HTTP response object and using it's fluent setcookie method call. <?php use Symfony\Component\HttpFoundation\Cookie; $cookie = Cookie::create('foo') ->withValue('bar') ->withExpires(strtotime('Fri, 20-May-2011 15:25:52 GMT')) ->withDomain('.example.com') ->withSecure(true) ->withPartitioned(); I've found that if you don't have classes to handle Request and Response, you end up cobbling together something that is redundant and less well designed and tested, so the other classes included in the component are well worth looking into. More Documentation here.
  15. You should not be trying to programmatically determine whether to call session_start. You should simply be calling it at the start of your index.php file. if it "loads" everything else, there is no need to have session_start calls anywhere but the index.php. The session will already be available to any of the include/required scripts. Remember that $_SERVER is a superglobal, and is always available globally.
  16. Right. It's an annoying issue with web development, but user input can never be trusted, and input validation must always be placed in both places. My approach has long been to start with the backend and insure that you are validating raw submission. This is where tools like postman are helpful. Once the backend is locked down, you can then move to validation in the HTML and javascript. You can get by without validation or HTML5 forms in the front end, but you can't get by without the backend validation.
  17. This comes down to some basic advice, particularly where databases are concerned (assuming you are using a sql database): Always use the right datatype. Money is a particular problem for floats, so depending on the database, you can either hack the use of an integer or if there's a datatype like the mysql DECIMAL type, something already designed to handle money without the potential for rounding errors. This also should tell you, that to support flexibility, your database should also include an indicator of the "type" of currency. If you implement a type table, your application will be able to know the difference between an amount that is stored in pounds or euros, or US dollars. Once you realize that floating point datatypes aren't good for handling calculations involving money, you then want to look into possible approaches. Even if you are using a DECIMAL field in the database, that doesn't insulate you from rounding errors if you read the values into PHP Floats and start doing calculations with those values. This is a few years old, but I think it's a good starting point for considering how your code works now, and potential ways to address currency and calculations that involve currency. In general, the display of data formatted in a way that is standard for an end user is referred to as "locale" and when you setup a personal workstation or server, you are asked questions that then configure the OS, typically using locale specific standards. So the presentation of a "currency" number and the actual currency that number represents should be a presentation issue. Unless you have a system that is actually storing values in multiple currencies (which would then add an entire extra layer of complexity that's probably beyond the scope of what you are currently working on), you should not be accepting strings that may or may not include a currency character, and then trying to manipulate them. That is all presentation logic, that should be separate, and essentially invisible to the inner workings of your application. Don't accept character fields in your form, and this problem goes away. If you want to add some intrinsic UI functionality that allows you to cut/paste a value, handle that in javascript and just strip out any non numeric characters.
  18. These models describe how the relational database engine handles concurrency. You don't DO anything. The Database does things for you, using various algorithms and whatever concurrency model you've configured it to use. These differ from RDBMS to RDBMS. This particular optimization is intended to deal with the processing of timestamped transactions in a transaction log that is being used to actually write out data. So by definition, this involves multiple "user/connections" that are trying to operate on the same row of data at close to/near the same time so that the transaction log is likely to have these read/write pairs of operations that could end up being in conflict with each other , and those scenarios are specific to an application and typically few/far between. In your case, for a banking transaction where you might need to debit/credit, you would wrap the changes inside a transaction, perhaps having issued a SELECT FOR UPDATE if the transaction would be updating a balance field. I'm not sure what the value of focusing on Minutiae like this provides, without any practical application or testing on your part. To examine how this all works, and what ramifications it would have, you would need to: Have a database that implements the Thomas's write rule Set up a database/tables Simulate the different scenarios (which is non-trivial as these would need to be separate sessions)
  19. That is just another way of saying you can create a responsive web application: viewport
  20. Certainly interesting project, but from what I've seen, very new and more like a proof of concept at present, rather than a legitimate contender in the cross platform mobile space. The mobile is also inherently closed source and requires a license, which is not the case for the many alternatives discussed. I mean you can develop cross platform mobile apps with commercial game development platforms like unity as well, but I didn't mention those. I don't object to the nativephp folks trying to build a business around their mobile platform, but the closed source nature of that makes this an apples/oranges comparison to the other options I listed.
  21. This is a large topic to cover. To start with, you can (and should) have been practicing "responsive" web UI development. So there's that option. Given you aren't interested in native development, you should look into cross platform mobile development options, which include: React Native (Typescript/Javascript) Flutter (Dart) Xamarin (.net/c#) Ionic (javascript/css/html) There are numerous other options which are less popular, but might be a better fit for you. Literally everything is going to be at very least object based, so your desire to avoid OOP is going to be problematic for you, although it is always possible to write essentially procedural code even though you have an object based framework. Your familiarity and use of javascript is one of the areas you need to explore, should you want to use React Native or several of these other web tech oriented bridge technologies. There's also overhead involved in certain frameworks where the app utilizes a built in javascript runtime, rather than strictly relying on the compilation process to produce native apps for your targets. Other options: Apache Cordova (Ionic built on top of it, so few would choose Cordova directly these days, for various reasons) Nativescript (javascript/html/css). Competes with Ionic, and depending on the app, might be better at delivering native mobile OS features Kotlin Multiplatform (Kotlin). This an interesting option you should look into. Kotlin was created by Jetbrains, which is the company best known for its editor tools, and in the php world, the generally acknowledged "best" IDE PHPStorm. You might be wondering about how this all came to be, but it makes more sense if you know a bit about the history of Java and Android. The official development language of Android initially was Java, and you created native Android apps using Java. Jetbrains IDE products are written in Java, and that began with what was their flagship editor IntelliJ Idea. So they have a long history as being a key technology company in the java development community. Kotlin was created to sort of be for Android, what Swift was for IOS -- an alternative to a more verbose, lower level language like Objective C or Java. The main advantage is that by learning Kotlin you are learning the recommended native Android development language, while also being able to create native IOS applications with Multiplatform. It's also a language that I think might accommodate your desire to write mostly procedural code.
  22. I only scanned your project but I have a few questions I'd like to see answered: Why would someone want to use your library when there are libraries like Guzzle or Symfony's HTTP Client that do the same thing? I didn't see any unit tests. Are you planning to add those? I think that's pretty much a requirement these days if you want people to adopt and have confidence using a new library.
  23. Quick additional comment. The result of fork is a new process, which I'm sure is clear. What you might be missing is that the child process is identical to the parent at the moment of the fork call. At that point you now have 2 identical processes that are proceeding from the point of the fork call, because they share the same call stack. I converted your pseudo code into a small c program and compiled on my mac. As the windows OS doesn't have fork and in general is entirely different this code would have to be compiled and run in WSL or a VM under windows #include <stdio.h> #include <unistd.h> // For fork int main() { int a = 50; if (fork() == 0) { a += 5; } else { a -= 5; } printf("Value of a: %d\n", a); return 0; } compile it and run: clang fork.c -o fork ./fork Output: Value of a: 45 Value of a: 55 At least under osx, it seems that the child process runs and exits first, although the underlying management of memory is left to the OS. It is likely that child processes will run first, because of the way memory is handled by the OS. Fork wants to copy the memory space of the parent to the child, but the OS wants to defer that and uses "Copy on Write". If it ends up being a situation where nothing in the child process differs, the OS doesn't need to copy memory, so the OS will likely opt to have the child process run before the parent process, but there's no strict rule or definition or relationship with fork, that requires one process to run before the other.
  24. Javascript allows for asynchronous functions. To understand how JS works in the browser there are some educational resources like this one, that help illustrate things that aren't easily understood just by looking at js code. While a highly watched video when released, if you do watch it, just keep in mind that it was created prior to ES6 was fully released and supported by the major browser engines. There are now a few visualizers like this one: https://www.jsv9000.app/ you can use to step through code. The Javascript engine allows for asynchronous functions through its implementation of a "Task Queue". Prior to ES6, asynchronous calls required callback functions. The use of many nested/interwoven asynchronous functions with various callback functions can be highly confusing, and for people used to procedural programming, it lead to confusion and a proliferation of functions often referred to as "callback" hell. Promises were introduced with ES6 as a way of organizing Async calls. "A Promise is an object representing the eventual completion or failure of an asynchronous operation." Along with support for promises, the javascript engines added a 2nd queue: the MicroTask queue. In particular, Promises were created to better support chaining asynchronous functions together, as in many situations, you want a series of functions to run, any of which can return out of order, and still be able to chain those results together in the order required. This comes up frequently when using external API's where there are a number of different calls being made within any specific area of code. I would just be regurgitating what is on this page to elaborate much further: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises For some people, the look of a series of chained Promises, each of which returns additional promise objects looks less procedural than they would like, particularly when there are chained async calls that need to be resolved in order. For that reason, ES7 included the async and await keywords and syntax. It's your choice as to whether you want to use async/await or just stick with promises, although there are some things that promises can do that are not as easily done (or perhaps done at all) just using async/await syntax. Again, I would defer to the explanation on MDN, and that page in general for more explanation and examples, as it begins with:
  25. Here's an overview, including debugging: Once you open the devtools view, "console" is one of the tabs. Any javascript errors will be displayed there, so that's a good first thing to check. In your js code you can do this as an alternative to what you were doing: document.addEventListener('DOMContentLoaded', () => { const applyBtn = document.getElementById('bulkApplyBtn'); if (applyBtn) { console.log('✅ Button found!'); applyBtn.addEventListener('click', onApplyBulk); } else { console.log('⚠️ applyBulkBtn not found in DOM.'); } }); With your dev tools open, and the console tab selected, you'll see those log statements when the page runs. For situations like this you probably want to open the dev tools view, and then reload the page, so it reinitializes. FIrefox and Safari have developer tools with these same features, but there are often small differences, and a learning curve that goes into whichever you choose to work with, but you don't have to use Chrome.
×
×
  • 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.