Jump to content

gizmola

Administrators
  • Posts

    5,539
  • Joined

  • Last visited

  • Days Won

    108

Everything posted by gizmola

  1. I am not a fan of these setups, as they install a bunch of software and server processes on your workstation. They were a nice solution back in the day, but now you can use virtualization with virtualbox/vagrant or use docker. With a machine with the resources you listed, that is plenty of horsepower to run lamp in containers. Some advantages to doing this: You don't have installations of the AMP stack running under windows You don't have to deal with upgrades/maintenance of them Nobody runs the AMP stack in production on anything other than Linux these days, so you are developing closer to/or exactly on the target OS you will deploy to You can easily run containers that let you simulate more complicated environments (for example, multiple PHP servers behind a load balancer) that would be very difficult to set up under AMP without hacking the hell out of the setup, which defeats the purpose. You can easily run different versions of the stack under vagrant/PHP. If I want to test the lastest version of PHP against some code, that is trivial with Docker. There is a learning curve to everything, but I would advise anyone to invest in learning how to use Docker, as it's the tool that most teams are using to develop and often to deploy.
  2. In the future, please use the <> button to insert code. I fixed it for you this time. You stated your timer was every 10 seconds, but your example shows it's 5 You should note that if you test it with something longer like 30000, after the initial render, the links don't work, so it's not a timing issue I don't know how many rows you are sending but it seems pretty inefficient to blow out the entire list every 5 seconds. The main issue I see is that you are only setting the click handler when the page loads. Once you reload the page, the reloaded li's won't have click handlers attached. So the simplest fix is to move the code that sets the click handlers inside the setInterval code. With that said, the update might perform faster if you just write your click handler function, and then have your button markup include the onclick="clickHandlerFunction()". This way the DOM doesn't have to process adding the click handler for every refresh.
  3. With no code to look at, there is nothing anyone can do to help you. A page where you are updating the contents every 10 seconds, and in the process blocking any interactivity, doesn't seem like a very good design to me. At very least, you should be checking to see if an update is even needed or relevant.
  4. The old school way of running php with apache was to use the mod_php apache module, which makes php a part of apache. So that was certainly different. You can think of php-fpm as a "php server" process. Using it with apache or nginx or any other http proxy means that php-fpm is running separately and being communicated with from the http server via fastcgi. Fastcgi is a specification that evolved from the original cgi spec, that was the earliest way a web server could be configured to send data to and from an external program. php-fpm is a php server that implements fastcgi, so it can be used with any http server or proxy that also supports fastcgi. One of the obvious things to notice is that the effective user running the php script can be different than the user that the apache process is running as. It also has some efficiency when compared to mod_php, for reasons I won't go into, but that I did examine in a blog post I made. One big problem with mod_php is that the apache child processes tend to grow and absorb memory when serving php, and this pool of child processes has to be used for every request, so even if apache is handling a request to return an image or css file, or other static content, the apache child process might be 500mb in terms of memory usage, because previously it had been used to run a php script. This is a big reason that nginx became popular, as it was always intended to be a high performance proxy, and always used fastcgi. With that said, when php-fpm runs a php process it still does so using the php configuration. It does have its own settings to manage fastcgi, so in that way it's got another group of settings that you have to configure, and areas where the communication between apache and php-fpm can have issues, so in that way it's more complicated.
  5. Yes, the CN name needs to match the hostname. You will have to add an entry on the PHP server that resolves to the IP. So make the CN something like mysqlserver1.dummydomain.internal, where dummydomain is whatever you want it to be. On the server running php make an /etc/hosts entry for that domain that resolves to the mysqlserver IP. Then when you connect, use the mysqlserver1.dummydomain.internal hostname. If you are using a version of php >= 7.1, an alternative solution that might work is to pass MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT in the flags parameter for mysqli_real_connect. Theoretically that gets you around the problem, and may be what is happening with the mysql CLI on whatever other machine you are testing with.
  6. Is the server "remote"? When you did your "command line mysql" verification, did you do that on the server or from your workstation? A "decode" of the files generated by the mysql_ssl_rsa_setup: ca.pem - the "certificate authority" public key for the self-signed certs that were generated. (You will want this file on your client) client-key.pem - the "client" private key they generated. (You will want this file on your client) client-cert.pem - the "client" certificate that was generated which goes along with the client-key. These are the files you would need available to your client. Ideally you want to make copies of those files in a directory (not under the web root) of the server running your php application, with read only permissions, but still readable by the user that the php process is running as. You need to pass an actual or relative path to the files, when you make mysqli_ssl_set initialization. mysqli_ssl_set($con,"/path/to/client-key.pem","/path/to/client-cert.pem","/path/to/ca.pem",NULL, NULL);
  7. You have hit a bug: https://bugs.php.net/bug.php?id=81145 The bug has been fixed, but apparently it's not been merged into a production release yet. For now you can try this workaround. Replace your copy() with the copyByChunk() function, and see if it solves your issue. Increasing the buffer size will probably help if the performance hit is substantial, but fair warning -- test this function out before you use it. I did no real testing of it. function copyByChunk($srcFile, $dstFile) { # Use 1mb chunks $bufferSizeBytes = 1048576; $bytes = 0; $src = fopen($srcFile, "rb"); $dst = fopen($dstFile, "w"); while (!feof($src)) { $bytes += fwrite($dst, fread($src, $bufferSizeBytes)); } fclose($src); fclose($dst); // return bytes written return $bytes; }
  8. We need more information: What OS are you running on? Is this a CLI program or something happening via webserver integration? What version of PHP are you using? Copying from where to where? Is this from one directory to another on the same server? From one server to another? From a local directory to an NFS mounted one? A snippet of the code that actually does the copying would be helpful Possibly you hit a limitation rectified in a more recent version of PHP. Most likely there are several alternatives you can use to get around the problem.
  9. First off, I understand what you are looking for, and it is in no way unusual to want to have instrumentation and information about what is happening. There are many products out there, first and foremost Google Analytics. There are also log "mining/reporting" systems available. Awstats is one of them, but it's pretty old and I haven't used it in a long time. I'm not sure how functional and up to date it is. Here's a partial Google list of "alternatives to Awstats": Dynatrace. LogicMonitor. New Relic One. Datadog. Sumo Logic. Graylog. LogDNA. Apache log4j. Of these I've used New Relic, and Sumo Logic in the recent past, so it just goes to show you the many commercial and non-commercial offerings in this space. One thing you sometimes need to do, to get the level of information you want, is to modify the web server log format, and sometimes to inject additional variables into the logs. Things like session id's and cookies can be added to the logs to help establish things that can't be surmised otherwise. The details of doing this are an aspect of system administration that depend on your specific webserver and hosting environment. One specific example, would be the IP address of the request. If your server has a load balancer in front of it, the IP address of all requests will be the load balancer, and not the actual client IP, so that is an example of where you need to customize the logs in order to see what is actually going on. There are many many products and companies out there that offer logging infrastructure. One I've used in the past, not just for webservers, but for analysis of an entire cluster is Splunk. With that said, Splunk is a pricey commercial option. One FOSS stack that has a lot of mindshare and users is the ELK Stack, which consists of a setup of Elastic Search, Logstash and Kibana. Each piece of that stack solves a particular part of the problem that companies with sometimes large and complicated infrastructures face in getting server side analytics. You can do some reading about it here: https://logz.io/learn/complete-guide-elk-stack/ This might be the type of server based analytics system you want, and is modern, scalable and far more functional than a simple log parser/web reports system like AWStats. Most companies use multiple different options, as each tends to have a strength and a weakness. Google Analytics has a lot of features, but of course, it depends on the client running its javascript, and thus isn't ever going to show you requests that were still processed but didn't load javascript. If there are errors or bugs in the javascript on the page, this might cause GA not to log correctly or at all. Still you want to configure and start using GA with your site, and you will find it already gives you a lot of the functionality you want, without you having to do anything within your infrastructure. In my experience companies often use a variety of different tools. Sometimes, just looking at web logs is not enough, or doesn't really help you understand something, and you need logs of multiple different services. You might need to look at graphs of webserver(s) and your database for example, to see that a problem your system was having was related to database load at a particular time, which was in turn related to some slow queries that were running tying up the database resources for a long period of time. Resources on the server itself, like available memory, amount of swap being used, and cpu load, might show you that your server is overloaded or low on disk space. There are different types of logging and monitoring you can setup, that can often provide valuable insights into issues you will never find just looking at web logs.
  10. This is a great point from @ginerjm Mixing "presentation" and "logic" is the best way to have hard to maintain code. PHP is intrinsically a templating product, in that you can put partial html scripts and include them easily. There are also numerous excellent and easy to integrate template systems. If you can separate the database/model related code from all the other code that is really just html, it will be easier to see how to approach things in a simple and maintainable way. The concept is certainly related to KISS and to breaking larger blocks of complicated interdependent code down into discreet functions that do one thing in a predictable way. From a database standpoint, your comment that "it creates a duplicate entry in my database if the value was already checked" also tells you that you are not using features of the database engine that will provide you data integrity. You can use constraints/indexes, as well as "UPSERTS" to help manage this. I would provide further examples, but I have no idea from your code snippets what your database looks like.
  11. Thanks for letting me know your outcome. This is what we are here for, but it's still nice to know that we helped.
  12. OR........... perhaps you just make a page call item.php, and you pass the id as a url parameter, query the data you need and present it. You can also use rewrites to make it look like a static url like /item/3. That used to be a benefit for SEO, but at this point search engines don't penalized you for having url parameters like item.php?id=3.
  13. Well yes, it violates relational database design rules, which are referred to as the rules of normalization or normal forms. This is in violation of the most basic rule, meaning your table can not be in 1st normal form, by doing what you are trying to do. See this article. Your instinct to put multiple values (categories) in a single column/row combination, tells you that you are going down the wrong path. Furthermore, if your table has category1, category2, category3 etc, then that is a repeating group which is also incorrect. There are many issues here: You can't add a new category position without changing the table structure & all associated queries Queries are ugly and inefficient because you will need to index every category column and have a query that has code like "if category1 = 3 or category2 = 3 or category3 =3" etc. What is the right structure? You need to understand the relationship between the entities (thing, category). Start with the relationship from "thing". What have you told us? "A thing can have many categories". So the relationship of thing -> category is "one thing to many categories". Now look at the relationship from category to thing. What do we know? "One category can define many things." So the relationship from category -> thing is "one category to many things". This tells you that the relationship between thing and category is actually Many to Many. Think about it for a minute, using simple examples. Thing1 (category1, category2, category5) category5 (thing1, thing20, thing1000) Currently you don't have a table for category. You need to make one. category -------- id smallint unsigned primary key AUTO_INCREMENT category varchar(80) This table should be loaded with all your 1-n categories. Create a table to resolve the many to many relationship between thing and category. Typically people name a table like this "thing_category". It only requires 2 values: thing_category -------------- thing_id category_id You can give this table its own unique primary autoincrement key if you want or define the primary key to be thing_id,category_id. It is important either way, that you have a key that guarantees uniqueness for a thing_id,category_id value. Hopefully can now see how you would use this table. If I want to set thing1 to have categories 3,7 and 9, then I only need to insert rows into thing_category of (1, 3), (1, 7), (1,9). To get the categories back out, you join the tables together. Your queries are simple when you need to query for a particular category -- just inner join thing to thing_category and specify WHERE category_id = 7, or whatever you need. If you want a few categories, the query can be WHERE category_id IN (3,7) etc. This also makes your system configurable and data driven, as new categories can be added to the category table at any time, and you can start to make use of them without having to change code, since nothing will be hard wired in.
  14. My suggestion would be to look at the template code, and look at what happens when you navigate to http://mentalhospital.rf.gd/index.php?/recent_pics. Whatever querying is done for that, you want to add some of that logic to the default/homepage section of code so that it selects however many pictures you want in this block. Then you'll need to edit the home page template and add this new block in whatever way you want. Like most packages of this sort, you have to go in and edit the theme file(s) to customize it beyond whatever customization options the package offers, which in this case, it appear are few.
  15. Each method or function should do one thing. You have lots of redundant/competing object instantiation going on. Think about what your classes do/are for. What purpose do you need. You also seem to have a basic misunderstanding of how class properties are available/used. 1st things 1st. One source file per class. Only the namespace statement and class code. The filename should match the classname. Once you get the hang of this things will start to come together quickly. 2 Things you can learn more about to upgrade your code/understanding of PHP Oop. Learn about PHP Namespaces. Start using them. Add composer to your project mix with an initial composer.json. PHP Namespaces: The basics of them PSR-4: How to name your classes and organize them in your source tree to match, so they can be autoloaded Using Composer for package management and autoloader generation Learn about Dependency Injection as a design pattern. This was suggested to you previously. A blog series on DI by Fabien Potencier, creator of the Symfony framework project To do PSR-0/4 compatible namespacing, you need an orgname. It doesn't matter what it is, but case matters. So for example, let's say you were writing things for Phpfreaks, and the team decided all code would use that as the organization name. Then the Top namespace is going to be Phpfreaks. In this example, Somename is a stand in for whatever you want to use for your code. Let's try a new Db class: <?php // Filename /src/Database/Db.php // In composer.json you will have a PSR-4 mapping for Somename mapping to your project src directory. You will place all your classes in directories beneath src, organized as you see fit. namespace Somename\Database\Db; class Db { private $host; private $dbName; private $user; private $pass; private $charset; private $pdo; public function __construct($host, $user, $pass, $dbName, $charset="utf8mb4") { $this->host = $host; $this->user = $user; $this->pass = $pass; $this->dbName = $dbName; $this->charset = $charset; $this->connect(); } protected function connect() { try { $dsn = "mysql:host=".$this->host.";dbName=".$this->dbName.";charset=".$this->charset; $this->pdo = new PDO($dsn, $user, $pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)); } catch (PDOException $e) { echo 'Error: '.$e->getMessage(); } } public function getConnection() { return $this->pdo; } } Before instantiating your Data class create a new instance of a DB class, passing in all the parameters to the constructor. In this example, charset is optional. The constructor will try to make the pdo connection. <?php use Somename\Database\Db; use Somename\Database\Data; $db = new Db('localhost', 'user', 'pw', 'database'); // Data class should store the $db parameter in a private variable in the constructor. $data = new Data($db); Then from within data you could be using $this->db for pdo connection related things.
  16. It seems like a pretty good design, however, having a Logo page with an image is kind of old school, and not accessible. You should have an alt tag at very least. You want to go over all the accessibility features and make sure you've implemented them properly. The front page of the site spacing could use some margins so your form elements don't bunch together quite as much. The actual results are ok. Having everything centered doesn't look great to me. I would probably suggest either a table or perhaps a ul. It's odd to see a paragraph with all the text center aligned so that the 2nd line with 5 words is in the middle of the first one. Again I'd fine tune the markup and css a bit, and perhaps have some subtle background colors and borders around the various result boxes, to make it look a little bit nicer. The pre tag for your whois information is not responsive. Styling it this way would probably be helpful. pre { white-space: pre-wrap; word-wrap: break-word; text-align: justify; }
  17. Yes, although again the UI is incorrect. Checkboxes are not mutually exclusive. So you are just doing this UI in the wrong way. Your form code is also wrong. You have a label that is hardwired to dark, yet you have variables toggling the value from light to dark. When a form is rendered, it should always be checked, because you are using the checkbox to toggle from light to dark. This means that a value for the checkbox will never be set in the way you using this. A newly rendered form will always have a value (light or dark) and will be checked. Once you uncheck it, you'll submit the form, and the checkbox will not be passed. However, to your question, you have 2 choices: Write a little js that checks the check/uncheck state and sets a hidden element, which you use on submit Just have php check for isset() or use array_key_exists. If ! isset() then it was unchecked. You want to check the request method to make sure the form was actually posted. Not that I'd advise this, but in this case, and again you have to be logical and clear, if the form is submitted, then you are looking to toggle the value. <php if ($_SERVER['REQUEST_METHOD'] == 'POST') { $mode = empty($_COOKIE['mode']) ? 'Light' : $_COOKIE['mode']; //Toggle it $mode = ($mode == 'Light') ? 'Dark' : 'Light'; setCookie('mode', $mode); } else { $mode = empty($_COOKIE['mode']) ? 'Light' : $_COOKIE['mode']; setCookie('mode', $mode); } // Now can use $mode to render ?> <input type="checkbox" onChange="this.form.submit()" value="<?= $mode ?>" name="mode" checked> <label for="mode"><?php echo "$mode Mode"; ?><label><br> Again when you think about it, the actual value of the checkbox is irrelevant as you are really going to toggle the cookie value on any submit. The other option is to use some js. Probably what I would do is use a hidden field, so that you could rely on the submission, but then when you have a cookie you are also relying on, this whole scheme makes less sense Something like this could work: <?php if ($_SERVER['REQUEST_METHOD'] == 'POST') { $mode = empty($_COOKIE['mode']) ? 'Light' : $_COOKIE['mode']; //Toggle it $mode = ($mode == 'Light') ? 'Dark' : 'Light'; setCookie('mode', $mode); } else { $mode = empty($_COOKIE['mode']) ? 'Light' : $_COOKIE['mode']; setCookie('mode', $mode); } ?> <!DOCTYPE html> <html lang="en"> <head> <title>Form Test</title> <script type="text/javascript"> function toggleMode() { let cb = document.getElementById("cbmode"); let newMode = document.getElementById("new_mode"); newMode.value = (cb.value == "Light") ? "Dark" : "Light"; console.log(newMode.value); document.getElementById("modeForm").submit(); } </script> </head> <body> <form id="modeForm" method="post"> <input type="checkbox" onChange="toggleMode()" value="<?= $mode ?>" id="cbmode" name="cbmode" checked> <label for="cbmode"><?php echo "$mode mode"; ?></label> <input id="new_mode" type="hidden" value="<?= $mode ?>"> </form> </body> </html>
  18. The biggest changes in the PHP world: Additions to the PHP language Deprecation of MySQL_ Addition of namespaces and PSR-1/Now PSR-4 Creation of Composer and packagist Ascension of git to standard (Github, Bitbucket, Gitlab) Big 2 MVC frameworks (Symfony/Laravel) Vast improvement and adoption of Component libraries, installed via composer Explosion of cloud computing/hosting The biggest changes to methodology: Move to using Docker & Docker-compose for development Use of Git For editors, most pro developers are using phpStorm. It's the best PHP IDE, and the one you most commonly see being used. Visual Studio Code is pretty competent, and is free. There are a few PHP extensions that make it quite competitive to phpStorm, but you have to do some work in getting it setup. Both editors have great support for docker and git, although I tend to be a cli person, and feel more comfortable having a terminal open and multiple displays. They both have integrated terminals and you can basically stay in the IDE window 99% of the time, when iterating. As a long time user/early adopter of virtualization (Xen, Virtuozzo, VMware, Parallels, Virtualbox, Vagrant) I have used nearly all the virtualization and development orchestration options at one time or another, but at this point, Containers have proven to be superior for development, when compared to full OS virtualization, and have become the primary platform for deployment at scale. Given your stack requirements, Docker is a great solution, because you can easily iterate through the various versions and combinations of the stack under Docker, without having to build full virtualized OS's or install any packages. Just use the Official Docker images for PHP and MySQL. The PHP container already has versions of apache, simplifying your setup. Git is a great facilitator for an upward migration process, as you can make a new branch each time you go up a PHP version, fixing things you need to fix as you go, and allowing you to switch back and forth between branches or have multiple git clones where you could conceivably be running an older version of the app against an older stack, while simultaneously running a newer version that is in the development process. For getting bootstrapped into Docker, there are projects like Devilbox, Laradock, or even my relatively new project docker4lamp. These can all provide a basis for you to get comfortable with Docker and how to orchestrate containers together. I'd promote Docker4lamp more in terms of its stack matching your target, but the purpose of the project is to have a latest/greatest stack for someone relatively new, but with a solution to all the various problems that new developers confront at some point. Being far simpler in scope than either devilbox or laradock, it might be easier to learn from, as you may want to have your own docker images and docker-compose added to your source. Needless to say there is an incredible amount of information you can find to help you jumpstart your understanding and use of Docker. Of the 2 "kitchen sink" packages I mentioned, probably laradock (which despite the name, will give you a complete set of containers to work with) is going to be easier to get up and running with. Quality documentation exists for both projects. Once you have done all the porting work you need to do, you can decide if you want to deploy onto an OS with packages as you have been in the past, or use Docker in production under Kubernetes or docker-compose on linux. I also have been a longtime Centos user, and recently setup a hosted vps under Alma. The main thing I learned is that you want to use dnf and not yum, but otherwise it looks like Centos. I will say that for a long time, the Centos official packages had to be worked around, and people were using epel and remi to get anything close to current. It's really a pain, and yet another reason to consider just running containers instead. For a reverse proxy, one relatively recent option that has emerged is traefik. It's a really nice option, and far less complex to get going than nginx or squid or ha. With that said, usually scalability involves substantial architectural decisions and the avoidance of building in things that require a monolithic infrastructure. Step 1 would be getting your app current to a supported version of PHP. You might also want to upgrade your MySQL version to something fresher. Step 2. would be looking at performance/scalability, if there are any significant issues. Full disclosure, most of the projects I've worked on in the last 10 years have been deployed within AWS.
  19. An unchecked checkbox isn't passed when a form is posted. You could correct for that, or you could use a more appropriate form element (radio button or select list).
  20. Just looking at your design, the obvious missing piece is that you don't know when a particular award-skill is passed, so that's a benefit to the system, although maybe that isn't something you can manifest at this juncture. Looks like your new tables would be: StudentAwardSkill ----------------- person_id award_id display_ord date_skill (optional) You need a unique index on (person_id, award_id, display_ord) The scary thing about the current design, is that if anyone were to modify the display_ord value of any skills, it would basically change/corrupt the entire meaning of any stored Skills in the StudentAwardTbl.skills column. You might be wondering how you can build the bridge I described: Your new app should only be concerned with writing out the proper relational design - writing rows to StudentAwardSkill. Your checks = UPSERT (typically use INSERT ignore.) You attempt to insert a new row for every checkbox using person_id, award_id, display_ord. Set date_skill to now() if you want to use that. The main issue with this design is the handling of "unchecked boxes" . An unchecked box means that you need to issue a delete against StudentAwardSkill, again for that person_id, award_id, display_ord combination. You will need a table named something like AwardSkillSync AwardSkillSync --------------- awardskillsync_id created_on (timestamp) changeby (tinyint) student_id award_id processed (tinyint, default 0) When your endpoint runs, you create a row in AwardSkillSync, with changeby = 1. StudentUpdateTrigger runs when StudentAwardTbl.skills is changed. Creates an AwardSkillSync row with changeby = 2 row. Now you are only left with writing a sync command line script. That script should query for oldest rows with processed = 0. It should SELECT for update, and depending on the changeby it will either look at the flags in StudentAwardSkill and conform the values in StudentAwardSkill to what is in that array OR query the values from StudentAwardSkill, and generate the string, updating it. If there are few users and few updates, most likely changes will be synchronized in either direction in what appears as near instantaneous fashion. There will be extra queries needed when a change is made in the old delphi system, but that is the cost to being able to have this bridge with no changes to the existing delphi system. The important thing to keep in mind for this to work, is that your sync routine should not update StudentAwardTbl.skllls if things are already correct. Just mark the row as processed. Although a bit less important, as no trigger is involved, would be any updates to StudentAwardSkill. Once the sync worked for either update, you could put it in a cron that you could run every second. You want to make sure that you use some type of semaphore that would prevent the job from running if another job was already in process.
  21. Systems are often hamstrung from the get-go with bad database design decisions. Since you are doing this for a charity (and I assume, donating your time?), I really don't see any reason to force yourself to build upon a poorly designed system. If you're doing this in part to hone your skills, then there's even less reason to reinforce a bad design, by building something new against it. There is a way to continue to use both systems, which is to create the tables you should have, then develop some bridge code that will keep them in sync. It's not simple, but it can be done, and then you won't be stuck with the mistakes of the past forever. As for updating in page, the answer is to use ajax. Have the button click submit values to an endpoint you develop that take the changes and modify the data as needed. Modern ajax code should be written using ES6 and best practice techniques: Use Fetch with promises (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) Pass data to/from your ajax endpoint in json format I don't know what version of bootstrap you are using, but resist the temptation to utilize jquery for this stuff, even though jquery does have the $.ajax() call, which could be used. As for your PHP endpoint, just think of it as the same script you might write if you had a standalone form that was submitting only the data you need to do this update. You will want to read the data from POST, json_decode it, and from there the actual processing should be straightforward.
  22. As an aside, Light/Dark themes are a great use case for SASS/SCSS. Here's a short article to illustrate some of the ideas.
  23. Hey I didn't name the field 😅 But my american upbringing says that "specialty" is good. I do like the english pronunciation of spe-cee-al-it-tee of your version though.
  24. My First comment: Don't use enums. I would recommend changing the definition of the field to a CHAR[1], and store either a 'P' or an 'S'. Your code should not interpolate values into your SQL even if you are escaping them. Use Prepared Statements. Your redirection code should be changed: if ($specialty == "pro") { header("Location: pro.php"); } elseif ($specialty == "stu") { header("Location: stu.php"); } else { die('Unknown Specialty.') } Note format of the Location header.
  25. I already debugged this for you. Did you use the code I posted? It was tested, and doesn't have any bugs involving the $ques variable being undefined.
×
×
  • 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.