Jump to content

gizmola

Administrators
  • Posts

    5,878
  • Joined

  • Last visited

  • Days Won

    139

Posts posted by gizmola

  1. I wouldn't worry about load testing until you have an MVP.  Unit tests are much more important in the development phase.

    With that said, a fast and simple way of running a load test, is to use the apache benchmark (ab) program, that is part of the apache server.  It's a simple cli program that you can use to send a bunch of requests using multiple socket connections.  You can also do some minimal authentication and post requests with it.  

    Beyond ab, there's a lot of other tools like Siege and JMeter, that have different strengths and use cases.

  2. I suggest you use the advice provided here:  https://phpdelusions.net/pdo#errors

    In a nutshell... don't use try catch around PDO code, unless you are checking for a common specific issue you can recover from.  

    The problem of a user trying to insert an existing email and thus triggering an exception due to the existence of a unique constraint on that column is one of the common places where you DO want to use a try catch block.  The example provided directly addresses this scenario, and you can see it's really the same thing that Barand gave you.  The answer you should have accepted was Barand's code, even though you had a syntax issue.

    Otherwise, most PDO code should not have try ... catch around it.

  3. In addition to the answer to your question from requinix, you have made some ill advised re-configuration of your server, in order to process .html files as if they were php scripts.  You should undo that, and use an index.php instead.  

    I will add that you could get around the issue of automatic output via output buffering, but I wouldn't advise trying to get around this issue with that solution when you have something so unsophisticated and clearly a 1st step towards actual implementation of what you really want.

    Typically what people do these days is implement some form of the "front controller" pattern.

    Under this pattern, the index.php becomes your front controller/bootstrap/kernel/router, and can also do the security checks (filtering) you require.  What you want then, is to have ALL requests for your site run through your front controller.  

    It can then take the requested "virtual" path, by parsing the request URL, and loading the code you want to make available, or prompt for authentication, return whatever HTTP response code you want, etc.

    This page from the symfony documentation illustrates ways to setup various different web server configurations to use index.php as the front controller:  https://symfony.com/doc/current/setup/web_server_configuration.html

    It's just a start, but once you get the idea you can come up with some simple static routing just using something as simple as a case statement, and require_once() of the code you want to run from there. One of the first sites I ever worked on essentially did just that for the majority of its routing.

     

     

  4. There are design patterns like Model-View-Controller (MVC) that already address these ideas.  Most frameworks implement the MVC pattern.

    How is this relevant to you?

    Your user data structure should be described in a "User" model class.  

    Frameworks give you a lot of base class functionality, but even without using a framework, you should be able to take the idea, and create your own.

    The models of the popular frameworks are otherwise known as "object relational mapper" aka ORM libraries, and of these there are a couple different pattern flavors:  the Data Mapper pattern (example: Doctrine ORM, Cycle ORM) or the Active Record pattern (Laravel Eloquent, CakePHP, others).

    Looking into the API's these libraries provide, can be the basis of your own home-grown highly simplified model classes.  The important idea to grasp, is that a model class in an ORM is the blueprint for how relational data is mapped to a php object when read, and stored into the database (or deleted) when written.

    The popular ORM's do a lot more than that, but as a starting point it's good to just think about those simple needs.

    To the point of setters and getters this often comes down to philosophy and pragmatism.  It is entirely possible to create a model class for a table that uses one or both of the __get and __set magic methods to provide you with $user->getCol1() and $user->setCol1() functionality without having to actually implement those methods.

    Conversely however, most ORM's require you to provide the attributes and setter/getter functions, and there are certainly cases where those are valuable to have.  

    However, when all is said and done, the bigger question is:  why don't you use one of these many ORM libraries instead of rolling your own ill conceived libraries?

     

  5. Ok, so I think we finally have an idea of what you are looking for:  You actually want to chart data from the CSV.

    In the olden days, this was typically done using one of many charting libraries that can be used to output an image format (gif/jpg/png) etc.

    Practically speaking, few people use those libraries these days, and instead, javascript libraries have become the best practice way of presenting data. You move the burden of presentation to the client, and it provides a lot more usability as well, when compared to having to output an image.  With the old php graphing libraries, images are also more difficult to maintain especially if you want to cache them, which is a good idea.  If the data is frequently being updated/replaced, it's also a huge logistic pain, where you have to build in intelligence into the process of determining when to (re)create a file.  Not caching the images and instead just generating them on the fly is a great way to crush your server.

    For all these reasons, people just render in their UI using clientside javascript.  You can also typically configure options to those libraries that let people download the graphs as an image, which is a built in for most of them.

    Your PHP code then becomes simply a translator from the original csv file(s) to the json format of the data you need to deliver to the javascript charting library you are using in your client code.

    There are many libraries, but I will point you to one I've used in the past, and is widely used throughout the industry, at least as a starting point:  https://www.highcharts.com/

    From there it's easy enough to find competitors/alternatives with a bit of searching.

    Just to give you an idea, some years ago I had projects using the php graph libries phplot and phpcharts.  Here's an old article about a hobby project I wrote and maintained for a while:  https://www.gizmola.com/blog/archives/63-PHPlot,-MySQL-and-the-Dark-Ages-of-Camelot.html

    Here's a Codepen I created using the Plotly js library, for a project one of my kids was doing in school many years ago:  https://codepen.io/gizmola/pen/MpjLeK

    Codepen and/or similar sandboxes can be a good way to experiment and get some experience with a particular library prior to doing the integration with your system.

     

     

  6. Scalability is also a concern.  Here is some food for thought.

    What is important for scalability is only the maximum number of concurrent users per second.  You need tools to help you simulate this type of load before you really can get an understanding of any potential bottlenecks or what concurrent load your system can handle and still operate.

    Assumption #1: you have a monolithic server. 

    What this means is that your application will run in a stack where everything (other than the database) will run on the same server.

    1. Sessions will use the filesystem
    2. images will be stored on the filesystem
    3. Database can be running on the same server or not
    4. Reverse proxy will run on the same server (assuming you are employing one).

    This sort of setup is typical, and has limited scalability, and suffers from contention issues when load increases.  If this is how your production will run, you at least want to learn a bit about how your setup performs as load increases.  Everything takes memory, and databases don't work well if they run out of memory or resources.  A frequent mistake people make in setting up a database is to provide inadequate memory allocation.  Databases are pretty much always given their own dedicated machine to run, for anything that isn't a hobby or non-commercial endeavor.

    Advantages to storing data on the filesystem:

    1. Filesystem already buffers data and is highly efficient
    2. The cost of returning data is only IO + bandwidth
      1. Stored in a database, a read of a blob requires IO + network delivery to application + network delivery to client
      2. Stored in the db, blob storge and retrieval is often non-optimal
      3. Stored in the db, blobs balloon the size of the database dataset, making database caching less effective, and can also slow down queries that touch the table(s) with the blobs in them.  

    In terms of security, you will need to store the files in a location that is not within web space (ie. under the webroot).  It is easy enough to write the routine you need that returns the data from a location on the filesystem. 

    Storing in a database does have this advantage, in terms of the potential for scalability:

    1. Making the application scalable is simpler, as you can have 1-n application servers connecting to the same database (and this is the 1st level typical of a move to a scalable architecture from what started as a monolithic app)
    2. This is another reason to start with a reverse proxy even with a monolithic architecture.
      1. Once you have app server #2 you have broken sessions
        1. You can move sessions into a database or distributed cache like memcached or redis
          1. Moving sessions into a DB can add a lot of load to the db
        2. You can use the reverse proxy to pin sessions (ie. "sticky sessions") to a specific app server.  Usually this is done using a cookie that the reverse proxy adds and subsequently uses to keep traffic coming back to the same app server once an initial connection is made.

    The other ways to scale an application that uses images stored on a filesystem:

    • Use an NFS server or NAS appliance
      • I've worked for a number of companies with large amounts of data and files.  In some cases, the problem could be solved with a NAS device, which servers can then mount using NFS as a client.
    • Use a file storage service
      • A good example of this is AWS S3. Some ISP's have their own alternative, and there are even consumer grade services like Dropbox you can make use of if you look into it.  Whether or not this is smart or feasible comes again down to the application infrastructure, but as a rule of thumb, you are more likely to have the app experience feel similar if the object storage is local/within your hosting infrastructure.  For example, if you had a server hosted by Linode, they offer an S3 compatible alternative service, and I'd look into that.  
        • The downside here is additional costs for the storage of the assets and possibly egress costs to retrieve.  There are a lot of different "Object Storage" companies out there, and they are intrinsically scalable, so it wouldn't hurt to do some research.
  7. Welcome to phpfreaks.  Please in the future use a code block.  I fixed your post this time.

    I haven't done anything with Oracle and PHP in quite a while, but my first thought would be to have you try providing the type constant parameters.  Your $p_employee_id is an integer, yet you are providing a length pertinent to a varchar, which doesn't make sense.  

    I'd experiment with this:

     

    oci_bind_by_name($statement, ':p_employee_id', $p_employee_id, -1);
    oci_bind_by_name($statement, ':result', $result, 255); // Assuming the result length is 255 characters

    See what happens.

    If that doesn't fix it, you also might try this:

    oci_bind_by_name($statement, ':p_employee_id', $p_employee_id, -1, SQLT_INT);
    oci_bind_by_name($statement, ':result', $result, 255, SQLT_CHR); // Assuming the result length is 255 characters

    Or even:

    oci_bind_by_name($statement, ':p_employee_id', $p_employee_id, -1, SQLT_INT);
    oci_bind_by_name($statement, ':result', $result, -1, SQLT_CHR); 

     

    Also the pl/sql code for the sproc might be helpful/necessary in figuring out what might be happening.

     

  8. 12 hours ago, kkroo1 said:

    Original poster here, many years later. Lost account access. Can a moderator or admin delete this thread?

    We don't delete threads, as per the TOS you agree to when you join.

    I removed the things in the script code that has PII in them.

  9. On 2/2/2024 at 3:23 AM, experience40 said:

     

    @Barand I noticed on the single query you suggested that you amended " .$company_id ." to {$company_id}, is {$company_id} more efficient or just the correct way to include it and also is it as safe to use to protect from injection?

    It's just an example of utilizing variable interpolation into a string.  In general it is easier to read and maintain code that doesn't have a bunch of unnecessary string concatenation, when you can just use interpolation as Barand did.

    • Like 1
  10. On 2/11/2024 at 4:18 PM, CSS-Regex said:

    Don't worry, I found the problem, and it wasn't the MySQL statement

    The SQL statement you had was definitely wrong.  LIMIT constrains a result set, and is not a valid part of a WHERE clause.  Whatever you might have fixed, you also must have fixed that issue.

  11. As an aside, when I see code like this....

     

    $buntingRefolding = $_POST['bunting-refolding'];                    
    $firstName = $_POST['your-first-name'];
    $surname = $_POST['your-surname'];
    $emailAddress = $_POST['your-email'];
    //etc

     

    I always wonder why.  Did they not understand PHP variables?  How to interpolate an array? 

    Well at any rate, before we can even begin to consider the issue, you need to define what "stopped working" means.   If it means that you used to get emails and you now don't, and nothing in the code has changed, the most likely culprit is that something in your hosting setup changed so that it no longer allows emails to be sent from your server (or they are being spam filtered because you don't have the things needed for a server and domain to allow.

    This code uses the mail() function, which is the lowest common denominator for sending mail, and is reliant on other MTA configuration in the OS.  There isn't a lot of visibility into what happens once the mail is dropped off to the MTA, which is a big reason that more sophisticated email libraries exist.  I don't know how old this code is, but wordpress has its own mailing function wp_mail() which wasn't used, so when you say that the other mail works, I would check that those routines were written the same way.  They might be using wp_mail() which wraps the phpmailer library.

  12. It also looks like you want to group the prior fulltext searches, so something like this?

     

    SELECT *, l.link_id
              , l.url
              , l.title
              , t.term
              , l.content_type
              , d.content
              , d.link_id
              , SUM(MATCH(t.term) AGAINST('w00t' IN BOOLEAN MODE) + MATCH(url, title) AGAINST('w00t') + MATCH(d.content) AGAINST('w00t'))  as `rank`
         FROM links l
              JOIN terms t ON l.link_id = t.link_id
              JOIN links_description d ON d.link_id = l.link_id
    
         WHERE (MATCH(t.term) AGAINST('w00t' IN BOOLEAN MODE)
               OR MATCH(url, title) AGAINST('w00t')    
               OR MATCH(content) AGAINST('w00t'))
         	   AND l.content_type = 'docume')
         GROUP BY title
         ORDER BY `rank` DESC LIMIT 200;

     

     

     

     

    • Great Answer 1
  13. 52 minutes ago, Olumide said:

    I understand your point, for instance storing names again in the invoice table when the names are available in the student table is like exhausting more spaces and I don't think it can last if the storage space is not much, it can crash. You and @Barand have contributed tremendously. I am not yet an expert like you all, but I believe in consistent practicing. 

     

    Glad you have taken advice.  In fact, what they have been warning you against has a technical name in the world of database design, and that is "de-normalization".  When you redundantly store data, you are moving away from the practice of "normalization" which is the correct design.

     

  14. 3 hours ago, fanta1066 said:

    Ok I am giving up, its far to complicated as I am not a PHP coder. And this has taken up to much of my time. 

    Sorry to see your valuable time was wasted by Barand providing you free professional consulting, custom built code and hand holding.  😣  

    • Like 2
  15. Off the top of my head 2 possibilities that might explain the issue:

    • Event scheduler was not started in server
    • Server is UTC, and event was UTC time, leading to confusion as to when the first event should have occurred.

    These are just guesses, but looking at the mysql error log, looking at the events table and commands like SHOW CREATE EVENTS and SHOW EVENTS might help you.

  16. 3 hours ago, webdeveloper123 said:

    Do you mean write a script that will generate it for me?

    Yes exactly. 

    The better known frameworks (symfony & laravel) come with cli libraries, but there are also many standalone libraries out there that take care of a lot of cli details, like providing argument handling.  For example:  https://splitbrain.github.io/php-cli/

    You don't need a cli library, but they can save you a lot of time.  At most rudimentary however, you can run a script using the cli,  with php -f. 

  17. It is always a good idea to enforce your business rules with constraints, whenever you are clear.

    As for loading in data for a system you've developed for an assignment, just generate a bunch of screening rows.  

    This type of seeding of data is fairly typical, and there are various libraries like faker (https://fakerphp.github.io/) that can be used for generating test data which are often used by developers.

  18. One other comment that might help you here:

    As far as I know, there isn't a built in extension to woocommerce that handles VAT, so if you are using some module/extension to provide this, that would be important to specify here.  There are various different modules available from what I've seen.

  19. The world of php when simple scripts like this were copy and paste jobs is long gone now.  The libraries requinix mentioned are certainly the way to go, but also typically require the use of the php dependency management tool composer, and a basic understanding of object oriented programming, in that these libraries are oop.  

    There is also the question of email deliverability.  These days, you really need to understand a good deal about how email works, and the various ways email is authenticated, or you can end up with a script that will send emails only to have them rejected or black-holed, or spam filtered, defeating the entire purpose of your endeavor.

    I'm sorry to say that this is just beyond what a neophyte can handle competently.  

  20. On 1/8/2024 at 2:10 PM, oem said:

    Basically I am writing a php based chatbot with the telegram api. I use xampp as a test environment so the script runs through a webserver. For now I always need to refesh the website for the script to run. I want it to run automatically in the background so that if a someone messages the bot he gets immadiately a answer.

    I was thinking of an infinite while-loop but then the website just loaded forever. I also heard of cronjobs but I does not allow to run a script every second.

    How can I get the script to run continuously in the background of the webserver?

    You 100% want to write this as a cli application, and do not want to run it as a web application.

    Cron used to be the way that people scheduled this type of thing, but with modern linux os's services now run under systemd.  Kicken provided a great example of how to write a systemd unit file.

    With that said, you will probably want to read this thread for more information on the format of the files and various capabilities. https://unix.stackexchange.com/questions/224992/where-do-i-put-my-systemd-unit-file

    I would suggest you start with what kicken provided, and read through the thread to answer questions that might come up, in terms of where to put the file.  Systemd has a lot of complexity to it, compared to the things it was designed to replace.  There are features that take care of issues that used to come up with services like semaphores to prevent race conditions, which used to be left to developers to code around (typically with shell scripts) and systemd now takes care of that problem for you, if you use the correct configuration.  

    As you should note from the example Kicken provided, there is "Restart=on-failure" which takes care of the problem of your chatbot dying and will restart it.  

  21. 6 hours ago, Andou said:

    Hello everyone! Joined because I did a bit too much lurking and fell down the PHP rabbit hole. I did try to go through Learn PHP The Right Way but gave up. I suppose there's room for a second chance (after I couldn't wrap my head around Smarty and Twig).

    I'm a hobbyist programmer and college student. I generally program in Python, having learned Java over 2020 and almost certainly forgotten about it, but there's something about PHP that seems interesting. Besides the fact a ton of websites run on it and it's easy to pick up (not necessarily master, though).

    I did mess around with Symfony and Laravel (truth be told, I preferred the former more) but never really dipped my toes in far enough. Hopefully that will soon change.

     

    The commonality of most frameworks, is that most of them are built using Object orientated design patterns, typically implementing the "Model View Controller" (MVC) pattern.  

    The model layer, when using a relational database is also an ORM.

    Symfony (and Laravel) are also frameworks, where the underlying pattern of library design is known as "Dependency Injection" (DI).  A big benefit in using Symfony or Laravel, is that they facilitate the use of components as services, and you also can easily write your own classes that can be used as services.  A quick example, that is frequently needed would be email services in the application.  Typically you add the mailing component library to your project, do a bit of config (and in many cases the basic config gets added for you if you use a symfony recipe package) and at that point actually using the library is trivial.  The "Dependency Injection Container" that comes with symfony can make decisions on when to load a library that is required (or not).  It is thus important to learn something about DI design for use in your own classes.  

    The originator/project lead of Symfony wrote these articles back in 2009, and I still recommend them to anyone trying to understand Dependency injection as a pattern.  Read here -> http://fabien.potencier.org/what-is-dependency-injection.html

    Once you have more comfort with Oop, and at least a basic appreciation of the existence of OOP design patterns, you will have a lot more comfort using any framework.  People who really are just trying to wade through a sophisticated framework without any understanding of how/why, can easily get lost, or have the feeling of not knowing what to do when they encounter an issue.

    With that said, here's a solid free course in Symfony 6, which if you can follow it, you will give you a good foothold in Symfony:  

     

     

    I am a long time Symfony user, going back to symfony 1, and the earliest versions of symfony 2.  Symfony 1 was an entirely different framework, and 2 was a very influential ground up rewrite that was intended to be a Dependency Injection framework from the start.  Almost every major component from Doctrine to Twig was based upon the existence and design philosophy of some other popular library from the Java world or in the case of Twig, from Python's Jinja and Django projects.  

    In most cases all frameworks start with models (the data persistence in a database) and routing configuration into controllers.  Views are "templates".  This is where you concentrate your markup code where appropriate.  Beyond that, a lot of the really good stuff in Symfony or Laravel is in handling of dependency injection, and in providing for features like "event handling" or "security" or "form building and handling".  Really smart people have worked on these frameworks and generally use well known and applicable object oriented design patterns like in the case of Laravel for example, the "Chain of Responsibility" pattern.  They don't come right out and say that, but after you study patterns a bit and look at how some of these features work, you may recognize them.  

    You don't need to know any of this to build apps with these frameworks, but you do need to understand basic PHP oop, and interfaces, type hinting, annotations (and now in PHP 8, attributes which have basically replaced the need for annotations) inheritance etc.

    You MUST get comfortable with Composer.  You MUST understand autoloading.  You MUST understand how autoloading works with your own classes, and where to put those when you need them.  It is possible to do full apps just using the models/controllers/twig templates in the places the symfony manual and tutorials tell you to put them, although this will often lead to lots of "not DRY" code and fat controllers.  From a learning standpoint, that's somewhat natural, and nothing to worry about, but eventually you will probably see the problems and seek to remedy them by creating your own classes, which will then be used as services in your controller code.  

    Last but not least, I highly recommend getting a handle on unit tests, and how to write and run them.  Test coverage is another area where these frameworks are an amazing value because the developers have worked hard to provide unit tests for their code, so there's a high degree of built in quality.  

    There are lots of frameworks out there, where people did their own take on a framework, and inevitably, they lack unit tests, documentation etc..

    One last thing on Symfonycasts.  Symfonycasts is a superb resource, started by the long time Symfony documentation lead, Ryan Weaver.  The tech built into the tutorial system is fantastic.  Full transcription, and code snippets built into everything, so you can alternate between reading or watching as you desire.  It costs $25 a month, and if you simply want to learn Symfony in all its sophistication, it's highly worth it, as you can sit down and power through the material in directed fashion.  There is a huge amount of material they have covered, but it can also be dense.   With the proliferation of javascript UI/UX frameworks like React and Vue, people aren't building apps the same way anymore, and there are a lot more apps where the backend is a REST api, and the frontend is built using a javascript framework, and pulls the data from the backend as a REST client.  Ryan has been adding a lot of content in these areas, reflecting the state of the art, and where the professional developer market has been going.  

    I would suggest getting a handle on the traditional first, and then perhaps looking at some of these emerging techs that look to better bridge frontend/backend code.  What I wouldn't recommend is buying a year subscription to save some bucks, and then finding out you didn't get enough use out of the subscription.  Better to pay the higher monthly and make sure you are getting value out of it.

    Last but not least, I really like "Programming with GIO"'s youtube channel for foundational state of the art PHP and things like autoloading/composer/core OOP etc.  It's free, and as good and probably better than a lot of paid courseware.  Symfonycasts and Laracasts both have that material available (sometimes free) but in my opinion you want to spend your time on the stuff that is specific to symfony or laravel rather than the general stuff, should you subscribe to these services in order to advance your education in how to use them.  

     

     

    • Like 1
  22. 55 minutes ago, Olumide said:

    I assumed symfony does not support MySQL database.

    Symfony is typically used with the Doctrine Object Relational Mapper (ORM) library.  The projects have long had a close collaboration.  Having done projects with many different frameworks over the years, my preference would be to use Doctrine as an ORM vs. alternatives like Laravel's Eloquent. 

    One reason for this, is that Eloquent is an implementation of the "Active Record" pattern, whereas, Doctrine is an implementation of the "Data Mapper" pattern.  These are differing approaches to how ORMS are designed to work. You can find many active record ORM's in the PHP world, going back to frameworks like CakePHP.  

    ORM's aren't quite as useful when using NoSQL databases like MongoDB.  I did a project where there was a mix of data persistence between MySQL and MongoDB, and there was some utility in using Doctrine to interface with both, but many of the features of an ORM are specific to relational databases, and document databases are just an entirely different way of looking at things with different strengths and weaknesses.  

    However, to conclude, Doctrine is a really great ORM to use with MySQL, and it is well integrated into Symfony, should you want to use it.

    • 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.